summaryrefslogtreecommitdiff
path: root/tests/src/JIT
diff options
context:
space:
mode:
authorTanner Gooding <tagoo@outlook.com>2019-05-09 13:46:38 -0700
committerGitHub <noreply@github.com>2019-05-09 13:46:38 -0700
commita74e710efb386677fc3b5c651b22213e996c0f72 (patch)
tree4bb169e475c9849066a3ed0cf3607d0392601354 /tests/src/JIT
parent2ff7aaac87a976a86c07b93867efb9ade391eed3 (diff)
downloadcoreclr-a74e710efb386677fc3b5c651b22213e996c0f72.tar.gz
coreclr-a74e710efb386677fc3b5c651b22213e996c0f72.tar.bz2
coreclr-a74e710efb386677fc3b5c651b22213e996c0f72.zip
More cleanup of the HWIntrinsic test templates (#24455)
* Adding some templates from which other HWIntrinsic test templates can be generated * Regenerating the HWIntrinsic tests
Diffstat (limited to 'tests/src/JIT')
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Add.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Add.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/AddSubtract.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/AddSubtract.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/And.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/And.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/AndNot.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/AndNot.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj5
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_ro.csproj3
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/BlendVariable.Double.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/BlendVariable.Single.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Ceiling.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Ceiling.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Divide.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Divide.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/DuplicateEvenIndexed.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/DuplicateEvenIndexed.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/DuplicateOddIndexed.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Floor.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Floor.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Max.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Max.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Min.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Min.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Multiply.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Multiply.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Or.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Or.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/PermuteVar.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/PermuteVar.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundCurrentDirection.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundCurrentDirection.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNearestInteger.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNearestInteger.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNegativeInfinity.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNegativeInfinity.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToPositiveInfinity.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToPositiveInfinity.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToZero.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToZero.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Subtract.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Subtract.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Byte.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Int16.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Int32.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Int64.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.SByte.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.UInt16.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.UInt32.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.UInt64.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Byte.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Int16.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Int32.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Int64.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.SByte.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.UInt16.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.UInt32.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.UInt64.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Byte.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Int16.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Int32.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Int64.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.SByte.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.UInt16.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.UInt32.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.UInt64.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Xor.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx/Xor.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.UInt64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.UInt64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Average.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Average.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj3
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_ro.csproj3
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Byte.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int16.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int32.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int64.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.SByte.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.UInt16.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.UInt32.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.UInt64.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Byte.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Int16.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Int32.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Int64.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.SByte.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.UInt16.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.UInt32.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.UInt64.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Byte.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Int16.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Int32.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Int64.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.SByte.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.UInt16.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.UInt32.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.UInt64.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.UInt64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyAddAdjacent.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyAddAdjacent.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyHigh.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyHigh.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyHighRoundScale.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.UInt64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackSignedSaturate.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackSignedSaturate.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackUnsignedSaturate.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackUnsignedSaturate.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/PermuteVar8x32.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/PermuteVar8x32.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/PermuteVar8x32.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmeticVariable.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Shuffle.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Shuffle.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Sign.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Sign.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Sign.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.UInt64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/SumAbsoluteDifferences.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.UInt64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx2_Vector128/ShiftRightArithmeticVariable.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx_Vector128/PermuteVar.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Avx_Vector128/PermuteVar.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/Fma_r.csproj2
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/Fma_ro.csproj2
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAdd.Double.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAdd.Single.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegated.Double.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegated.Single.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegatedScalar.Double.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegatedScalar.Single.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddScalar.Double.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddScalar.Single.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddSubtract.Double.cs248
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddSubtract.Single.cs248
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtract.Double.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtract.Single.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractAdd.Double.cs248
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractAdd.Single.cs248
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegated.Double.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegated.Single.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegatedScalar.Double.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegatedScalar.Single.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractScalar.Double.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractScalar.Single.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/Fma_r.csproj2
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/Fma_ro.csproj2
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAdd.Double.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAdd.Single.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddNegated.Double.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddNegated.Single.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddSubtract.Double.cs248
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddSubtract.Single.cs248
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtract.Double.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtract.Single.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractAdd.Double.cs248
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractAdd.Single.cs248
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractNegated.Double.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractNegated.Single.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/AlternatingBinOpTest_DataTable.cs69
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/AlternatingTernOpTest_DataTable.cs79
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanBinOpTest.template392
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanBinOpTest_DataTable.cs61
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanCmpOpTest_DataTable.cs61
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanTwoCmpOpTest_DataTable.cs61
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanUnOpTest.template354
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanUnOpTest_DataTable.cs51
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx115
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/HorizontalBinOpTest.template418
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/HorizontalBinOpTest_DataTable.cs69
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/SimpleTernOpTest.template439
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/SimpleTernOpTest_DataTable.cs79
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/SimpleUnOpTest.template385
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/_BinaryOpTestTemplate.template (renamed from tests/src/JIT/HardwareIntrinsics/X86/Shared/SimpleBinOpTest.template)125
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/_BooleanBinaryOpTestTemplate.template (renamed from tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanCmpOpTest.template)221
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/_BooleanUnaryOpTestTemplate.template (renamed from tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanTwoCmpOpTest.template)309
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/_TernaryOpTestTemplate.template (renamed from tests/src/JIT/HardwareIntrinsics/X86/Shared/AlternatingTernOpTest.template)277
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Shared/_UnaryOpTestTemplate.template (renamed from tests/src/JIT/HardwareIntrinsics/X86/Shared/AlternatingBinOpTest.template)300
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/Add.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/AddScalar.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/And.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/AndNot.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqual.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThan.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqual.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThan.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqual.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqual.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThan.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqual.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThan.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqual.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrdered.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarEqual.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarGreaterThan.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarGreaterThanOrEqual.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarLessThan.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarLessThanOrEqual.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotEqual.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotGreaterThan.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotGreaterThanOrEqual.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotLessThan.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotLessThanOrEqual.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrdered.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedEqual.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedGreaterThan.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedGreaterThanOrEqual.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedLessThan.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedLessThanOrEqual.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedNotEqual.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnordered.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedEqual.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedGreaterThan.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedGreaterThanOrEqual.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedLessThan.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedLessThanOrEqual.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedNotEqual.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnordered.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/Divide.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/DivideScalar.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/Max.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/MaxScalar.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/Min.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/MinScalar.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/Multiply.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/MultiplyScalar.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/Or.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_r.csproj6
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_ro.csproj4
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/Subtract.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/SubtractScalar.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse/Xor.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarEqual.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarGreaterThan.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarGreaterThanOrEqual.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarLessThan.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarLessThanOrEqual.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotEqual.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotGreaterThan.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotGreaterThanOrEqual.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotLessThan.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotLessThanOrEqual.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrdered.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedEqual.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedGreaterThan.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedGreaterThanOrEqual.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedLessThan.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedLessThanOrEqual.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedNotEqual.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnordered.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedEqual.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedGreaterThan.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedGreaterThanOrEqual.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedLessThan.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedLessThanOrEqual.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedNotEqual.Boolean.cs222
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyAddAdjacent.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyLow.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyLow.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackUnsignedSaturate.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj5
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj5
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/SumAbsoluteDifferences.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse3/AddSubtract.Double.cs213
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse3/AddSubtract.Single.cs213
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalAdd.Double.cs213
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalAdd.Single.cs213
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalSubtract.Double.cs213
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalSubtract.Single.cs213
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse3/Sse3_r.csproj2
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse3/Sse3_ro.csproj2
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41.X64/Sse41.X64_r.csproj1
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41.X64/Sse41.X64_ro.csproj1
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Byte.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Double.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Int16.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Int32.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Int64.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.SByte.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Single.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.UInt16.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.UInt32.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.UInt64.cs250
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/Ceiling.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/Ceiling.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/CeilingScalar.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/CeilingScalar.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/CompareEqual.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/CompareEqual.UInt64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/Floor.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/Floor.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/FloorScalar.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/FloorScalar.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.UInt16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/MultiplyLow.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/MultiplyLow.UInt32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/PackUnsignedSaturate.UInt16.cs213
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirection.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirection.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirectionScalar.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirectionScalar.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestInteger.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestInteger.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestIntegerScalar.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestIntegerScalar.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinity.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinity.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinityScalar.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinityScalar.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinity.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinity.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinityScalar.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinityScalar.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZero.Double.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZero.Single.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZeroScalar.Double.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZeroScalar.Single.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/Sse41_r.csproj7
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/Sse41_ro.csproj7
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Byte.cs259
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Int16.cs259
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Int32.cs259
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Int64.cs259
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.SByte.cs259
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.UInt16.cs259
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.UInt32.cs259
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.UInt64.cs259
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Byte.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Int16.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Int32.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Int64.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.SByte.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.UInt16.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.UInt32.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.UInt64.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Byte.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Int16.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Int32.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Int64.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.SByte.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.UInt16.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.UInt32.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.UInt64.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Byte.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Int16.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Int32.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Int64.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.SByte.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.UInt16.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.UInt32.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.UInt64.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Byte.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Int16.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Int32.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Int64.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.SByte.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.UInt16.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.UInt32.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.UInt64.cs251
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Byte.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Int16.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Int32.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Int64.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.SByte.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.UInt16.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.UInt32.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.UInt64.cs239
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse42/CompareGreaterThan.Int64.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse42/Sse42_r.csproj2
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Sse42/Sse42_ro.csproj2
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Abs.Byte.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Abs.UInt16.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Abs.UInt32.cs264
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalAdd.Int16.cs213
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalAdd.Int32.cs213
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalAddSaturate.Int16.cs213
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalSubtract.Int16.cs213
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalSubtract.Int32.cs213
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalSubtractSaturate.Int16.cs213
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/MultiplyAddAdjacent.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/MultiplyHighRoundScale.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Shuffle.Byte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Shuffle.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Sign.Int16.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Sign.Int32.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Sign.SByte.cs93
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Ssse3_r.csproj2
-rw-r--r--tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Ssse3_ro.csproj2
593 files changed, 69912 insertions, 18357 deletions
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Add.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Add.Double.cs
index 59caf0afc1..958f4d3e70 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Add.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Add.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld1;
private Vector256<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var result = Avx.Add(left, right);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var result = Avx.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.Add(left, right);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.Add(left, right);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> left, Vector256<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Add.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Add.Single.cs
index fd86f1c229..1028c6bae8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Add.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Add.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld1;
private Vector256<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var result = Avx.Add(left, right);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var result = Avx.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.Add(left, right);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.Add(left, right);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> left, Vector256<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/AddSubtract.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/AddSubtract.Double.cs
index c3e5e39e82..2d178ffc6f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/AddSubtract.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/AddSubtract.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddSubtractDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld1;
private Vector256<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddSubtractDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var result = Avx.AddSubtract(left, right);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var result = Avx.AddSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.AddSubtract(left, right);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.AddSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.AddSubtract(left, right);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.AddSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> left, Vector256<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/AddSubtract.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/AddSubtract.Single.cs
index 90db81f970..bf69a69251 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/AddSubtract.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/AddSubtract.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddSubtractSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld1;
private Vector256<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddSubtractSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var result = Avx.AddSubtract(left, right);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var result = Avx.AddSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.AddSubtract(left, right);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.AddSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.AddSubtract(left, right);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.AddSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> left, Vector256<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/And.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/And.Double.cs
index 37ea8eceea..e4343e68c7 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/And.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/And.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld1;
private Vector256<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var result = Avx.And(left, right);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var result = Avx.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.And(left, right);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.And(left, right);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> left, Vector256<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/And.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/And.Single.cs
index 6f46db5cda..9abd315e93 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/And.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/And.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld1;
private Vector256<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var result = Avx.And(left, right);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var result = Avx.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.And(left, right);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.And(left, right);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> left, Vector256<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/AndNot.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/AndNot.Double.cs
index 46e5af624f..d6509b4a15 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/AndNot.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/AndNot.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld1;
private Vector256<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var result = Avx.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var result = Avx.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.AndNot(left, right);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.AndNot(left, right);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> left, Vector256<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/AndNot.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/AndNot.Single.cs
index 4a2d3c598c..bcde820c8f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/AndNot.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/AndNot.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld1;
private Vector256<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var result = Avx.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var result = Avx.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.AndNot(left, right);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.AndNot(left, right);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> left, Vector256<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj
index 748f20ceed..5daa77a9d6 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_r.csproj
@@ -150,11 +150,8 @@
<Compile Include="Xor.Double.cs" />
<Compile Include="Xor.Single.cs" />
<Compile Include="Program.Avx.cs" />
- <Compile Include="..\Shared\BooleanBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\BooleanTwoCmpOpTest_DataTable.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_ro.csproj
index 84d60ff5dc..60b0c1c5a1 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Avx_ro.csproj
@@ -150,11 +150,8 @@
<Compile Include="Xor.Double.cs" />
<Compile Include="Xor.Single.cs" />
<Compile Include="Program.Avx.cs" />
- <Compile Include="..\Shared\BooleanBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\BooleanTwoCmpOpTest_DataTable.cs" />
<Compile Include="..\Shared\Program.cs" />
<Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/BlendVariable.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/BlendVariable.Double.cs
index 269d7db36d..b342c57905 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/BlendVariable.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/BlendVariable.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (double)(((i % 2) == 0) ? -0.0 : 1.0); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableDouble testClass)
+ {
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ fixed (Vector256<Double>* pFld2 = &_fld2)
+ fixed (Vector256<Double>* pFld3 = &_fld3)
+ {
+ var result = Avx.BlendVariable(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld2;
private Vector256<Double> _fld3;
- private SimpleTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (double)(((i % 2) == 0) ? -0.0 : 1.0); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Avx.BlendVariable(
+ Avx.LoadVector256((Double*)(pClsVar1)),
+ Avx.LoadVector256((Double*)(pClsVar2)),
+ Avx.LoadVector256((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray3Ptr);
- var result = Avx.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray3Ptr);
+ var result = Avx.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Double*)(_dataTable.inArray3Ptr));
- var result = Avx.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Double*)(_dataTable.inArray3Ptr));
+ var result = Avx.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray3Ptr));
- var result = Avx.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray3Ptr));
+ var result = Avx.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableDouble();
+
+ fixed (Vector256<Double>* pFld1 = &test._fld1)
+ fixed (Vector256<Double>* pFld2 = &test._fld2)
+ fixed (Vector256<Double>* pFld3 = &test._fld3)
+ {
+ var result = Avx.BlendVariable(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ fixed (Vector256<Double>* pFld2 = &_fld2)
+ fixed (Vector256<Double>* pFld3 = &_fld3)
+ {
+ var result = Avx.BlendVariable(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.BlendVariable(
+ Avx.LoadVector256((Double*)(&test._fld1)),
+ Avx.LoadVector256((Double*)(&test._fld2)),
+ Avx.LoadVector256((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> firstOp, Vector256<Double> secondOp, Vector256<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, Vector256<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.BlendVariable)}<Double>(Vector256<Double>, Vector256<Double>, Vector256<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/BlendVariable.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/BlendVariable.Single.cs
index d8dd9e36c5..4d0b4789f1 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/BlendVariable.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/BlendVariable.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (float)(((i % 2) == 0) ? -0.0 : 1.0); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableSingle testClass)
+ {
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ fixed (Vector256<Single>* pFld2 = &_fld2)
+ fixed (Vector256<Single>* pFld3 = &_fld3)
+ {
+ var result = Avx.BlendVariable(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld2;
private Vector256<Single> _fld3;
- private SimpleTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (float)(((i % 2) == 0) ? -0.0 : 1.0); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Avx.BlendVariable(
+ Avx.LoadVector256((Single*)(pClsVar1)),
+ Avx.LoadVector256((Single*)(pClsVar2)),
+ Avx.LoadVector256((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray3Ptr);
- var result = Avx.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray3Ptr);
+ var result = Avx.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Single*)(_dataTable.inArray3Ptr));
- var result = Avx.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Single*)(_dataTable.inArray3Ptr));
+ var result = Avx.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray3Ptr));
- var result = Avx.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray3Ptr));
+ var result = Avx.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableSingle();
+
+ fixed (Vector256<Single>* pFld1 = &test._fld1)
+ fixed (Vector256<Single>* pFld2 = &test._fld2)
+ fixed (Vector256<Single>* pFld3 = &test._fld3)
+ {
+ var result = Avx.BlendVariable(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ fixed (Vector256<Single>* pFld2 = &_fld2)
+ fixed (Vector256<Single>* pFld3 = &_fld3)
+ {
+ var result = Avx.BlendVariable(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.BlendVariable(
+ Avx.LoadVector256((Single*)(&test._fld1)),
+ Avx.LoadVector256((Single*)(&test._fld2)),
+ Avx.LoadVector256((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> firstOp, Vector256<Single> secondOp, Vector256<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, Vector256<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.BlendVariable)}<Single>(Vector256<Single>, Vector256<Single>, Vector256<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Ceiling.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Ceiling.Double.cs
index 985ddeb20c..492757e7be 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Ceiling.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Ceiling.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__CeilingDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Double> _fld;
+ public Vector256<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__CeilingDouble testClass)
{
- var result = Avx.Ceiling(_fld);
+ var result = Avx.Ceiling(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__CeilingDouble testClass)
+ {
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx.Ceiling(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector256<Double> _clsVar;
+ private static Vector256<Double> _clsVar1;
- private Vector256<Double> _fld;
+ private Vector256<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__CeilingDouble()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
}
public SimpleUnaryOpTest__CeilingDouble()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.Ceiling(
- Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.Ceiling(
- Avx.LoadVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.Ceiling(
- Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.Ceiling), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.Ceiling), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.Ceiling), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.Ceiling(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.Ceiling(
+ Avx.LoadVector256((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr);
- var result = Avx.Ceiling(firstOp);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var result = Avx.Ceiling(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArrayPtr));
- var result = Avx.Ceiling(firstOp);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx.Ceiling(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr));
- var result = Avx.Ceiling(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx.Ceiling(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__CeilingDouble();
- var result = Avx.Ceiling(test._fld);
+ var result = Avx.Ceiling(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__CeilingDouble();
+
+ fixed (Vector256<Double>* pFld1 = &test._fld1)
+ {
+ var result = Avx.Ceiling(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.Ceiling(_fld);
+ var result = Avx.Ceiling(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx.Ceiling(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.Ceiling(test._fld);
+ var result = Avx.Ceiling(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.Ceiling(
+ Avx.LoadVector256((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.Ceiling)}<Double>(Vector256<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Ceiling.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Ceiling.Single.cs
index ee2fd1c5ca..67934ce65b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Ceiling.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Ceiling.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__CeilingSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Single> _fld;
+ public Vector256<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__CeilingSingle testClass)
{
- var result = Avx.Ceiling(_fld);
+ var result = Avx.Ceiling(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__CeilingSingle testClass)
+ {
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.Ceiling(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector256<Single> _clsVar;
+ private static Vector256<Single> _clsVar1;
- private Vector256<Single> _fld;
+ private Vector256<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__CeilingSingle()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
}
public SimpleUnaryOpTest__CeilingSingle()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.Ceiling(
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.Ceiling(
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.Ceiling(
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.Ceiling), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.Ceiling), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.Ceiling), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.Ceiling(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.Ceiling(
+ Avx.LoadVector256((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr);
- var result = Avx.Ceiling(firstOp);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var result = Avx.Ceiling(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.Ceiling(firstOp);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.Ceiling(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.Ceiling(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.Ceiling(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__CeilingSingle();
- var result = Avx.Ceiling(test._fld);
+ var result = Avx.Ceiling(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__CeilingSingle();
+
+ fixed (Vector256<Single>* pFld1 = &test._fld1)
+ {
+ var result = Avx.Ceiling(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.Ceiling(_fld);
+ var result = Avx.Ceiling(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.Ceiling(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.Ceiling(test._fld);
+ var result = Avx.Ceiling(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.Ceiling(
+ Avx.LoadVector256((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.Ceiling)}<Single>(Vector256<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Divide.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Divide.Double.cs
index e9cfd181c6..56f8ade91c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Divide.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Divide.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__DivideDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld1;
private Vector256<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__DivideDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var result = Avx.Divide(left, right);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var result = Avx.Divide(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.Divide(left, right);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.Divide(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.Divide(left, right);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.Divide(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> left, Vector256<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Divide.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Divide.Single.cs
index ef695957c4..3e097b87e3 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Divide.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Divide.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__DivideSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld1;
private Vector256<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__DivideSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var result = Avx.Divide(left, right);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var result = Avx.Divide(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.Divide(left, right);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.Divide(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.Divide(left, right);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.Divide(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> left, Vector256<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/DuplicateEvenIndexed.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/DuplicateEvenIndexed.Double.cs
index fefeacf439..781c355dc6 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/DuplicateEvenIndexed.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/DuplicateEvenIndexed.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__DuplicateEvenIndexedDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Double> _fld;
+ public Vector256<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__DuplicateEvenIndexedDouble testClass)
{
- var result = Avx.DuplicateEvenIndexed(_fld);
+ var result = Avx.DuplicateEvenIndexed(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__DuplicateEvenIndexedDouble testClass)
+ {
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx.DuplicateEvenIndexed(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector256<Double> _clsVar;
+ private static Vector256<Double> _clsVar1;
- private Vector256<Double> _fld;
+ private Vector256<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__DuplicateEvenIndexedDouble()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
}
public SimpleUnaryOpTest__DuplicateEvenIndexedDouble()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.DuplicateEvenIndexed(
- Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.DuplicateEvenIndexed(
- Avx.LoadVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.DuplicateEvenIndexed(
- Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.DuplicateEvenIndexed), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.DuplicateEvenIndexed), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.DuplicateEvenIndexed), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.DuplicateEvenIndexed(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.DuplicateEvenIndexed(
+ Avx.LoadVector256((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr);
- var result = Avx.DuplicateEvenIndexed(firstOp);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var result = Avx.DuplicateEvenIndexed(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArrayPtr));
- var result = Avx.DuplicateEvenIndexed(firstOp);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx.DuplicateEvenIndexed(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr));
- var result = Avx.DuplicateEvenIndexed(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx.DuplicateEvenIndexed(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__DuplicateEvenIndexedDouble();
- var result = Avx.DuplicateEvenIndexed(test._fld);
+ var result = Avx.DuplicateEvenIndexed(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__DuplicateEvenIndexedDouble();
+
+ fixed (Vector256<Double>* pFld1 = &test._fld1)
+ {
+ var result = Avx.DuplicateEvenIndexed(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.DuplicateEvenIndexed(_fld);
+ var result = Avx.DuplicateEvenIndexed(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx.DuplicateEvenIndexed(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.DuplicateEvenIndexed(test._fld);
+ var result = Avx.DuplicateEvenIndexed(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.DuplicateEvenIndexed(
+ Avx.LoadVector256((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.DuplicateEvenIndexed)}<Double>(Vector256<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/DuplicateEvenIndexed.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/DuplicateEvenIndexed.Single.cs
index 0d98f6aa2e..a2629ee4ff 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/DuplicateEvenIndexed.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/DuplicateEvenIndexed.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__DuplicateEvenIndexedSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Single> _fld;
+ public Vector256<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__DuplicateEvenIndexedSingle testClass)
{
- var result = Avx.DuplicateEvenIndexed(_fld);
+ var result = Avx.DuplicateEvenIndexed(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__DuplicateEvenIndexedSingle testClass)
+ {
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.DuplicateEvenIndexed(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector256<Single> _clsVar;
+ private static Vector256<Single> _clsVar1;
- private Vector256<Single> _fld;
+ private Vector256<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__DuplicateEvenIndexedSingle()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
}
public SimpleUnaryOpTest__DuplicateEvenIndexedSingle()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.DuplicateEvenIndexed(
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.DuplicateEvenIndexed(
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.DuplicateEvenIndexed(
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.DuplicateEvenIndexed), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.DuplicateEvenIndexed), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.DuplicateEvenIndexed), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.DuplicateEvenIndexed(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.DuplicateEvenIndexed(
+ Avx.LoadVector256((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr);
- var result = Avx.DuplicateEvenIndexed(firstOp);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var result = Avx.DuplicateEvenIndexed(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.DuplicateEvenIndexed(firstOp);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.DuplicateEvenIndexed(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.DuplicateEvenIndexed(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.DuplicateEvenIndexed(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__DuplicateEvenIndexedSingle();
- var result = Avx.DuplicateEvenIndexed(test._fld);
+ var result = Avx.DuplicateEvenIndexed(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__DuplicateEvenIndexedSingle();
+
+ fixed (Vector256<Single>* pFld1 = &test._fld1)
+ {
+ var result = Avx.DuplicateEvenIndexed(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.DuplicateEvenIndexed(_fld);
+ var result = Avx.DuplicateEvenIndexed(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.DuplicateEvenIndexed(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.DuplicateEvenIndexed(test._fld);
+ var result = Avx.DuplicateEvenIndexed(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.DuplicateEvenIndexed(
+ Avx.LoadVector256((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.DuplicateEvenIndexed)}<Single>(Vector256<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/DuplicateOddIndexed.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/DuplicateOddIndexed.Single.cs
index e2e81640a7..32f98ba831 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/DuplicateOddIndexed.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/DuplicateOddIndexed.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__DuplicateOddIndexedSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Single> _fld;
+ public Vector256<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__DuplicateOddIndexedSingle testClass)
{
- var result = Avx.DuplicateOddIndexed(_fld);
+ var result = Avx.DuplicateOddIndexed(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__DuplicateOddIndexedSingle testClass)
+ {
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.DuplicateOddIndexed(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector256<Single> _clsVar;
+ private static Vector256<Single> _clsVar1;
- private Vector256<Single> _fld;
+ private Vector256<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__DuplicateOddIndexedSingle()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
}
public SimpleUnaryOpTest__DuplicateOddIndexedSingle()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.DuplicateOddIndexed(
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.DuplicateOddIndexed(
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.DuplicateOddIndexed(
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.DuplicateOddIndexed), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.DuplicateOddIndexed), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.DuplicateOddIndexed), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.DuplicateOddIndexed(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.DuplicateOddIndexed(
+ Avx.LoadVector256((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr);
- var result = Avx.DuplicateOddIndexed(firstOp);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var result = Avx.DuplicateOddIndexed(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.DuplicateOddIndexed(firstOp);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.DuplicateOddIndexed(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.DuplicateOddIndexed(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.DuplicateOddIndexed(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__DuplicateOddIndexedSingle();
- var result = Avx.DuplicateOddIndexed(test._fld);
+ var result = Avx.DuplicateOddIndexed(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__DuplicateOddIndexedSingle();
+
+ fixed (Vector256<Single>* pFld1 = &test._fld1)
+ {
+ var result = Avx.DuplicateOddIndexed(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.DuplicateOddIndexed(_fld);
+ var result = Avx.DuplicateOddIndexed(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.DuplicateOddIndexed(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.DuplicateOddIndexed(test._fld);
+ var result = Avx.DuplicateOddIndexed(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.DuplicateOddIndexed(
+ Avx.LoadVector256((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.DuplicateOddIndexed)}<Single>(Vector256<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Floor.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Floor.Double.cs
index 095efaf3e3..1e4c700312 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Floor.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Floor.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__FloorDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Double> _fld;
+ public Vector256<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__FloorDouble testClass)
{
- var result = Avx.Floor(_fld);
+ var result = Avx.Floor(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__FloorDouble testClass)
+ {
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx.Floor(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector256<Double> _clsVar;
+ private static Vector256<Double> _clsVar1;
- private Vector256<Double> _fld;
+ private Vector256<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__FloorDouble()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
}
public SimpleUnaryOpTest__FloorDouble()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.Floor(
- Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.Floor(
- Avx.LoadVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.Floor(
- Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.Floor), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.Floor), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.Floor), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.Floor(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.Floor(
+ Avx.LoadVector256((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr);
- var result = Avx.Floor(firstOp);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var result = Avx.Floor(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArrayPtr));
- var result = Avx.Floor(firstOp);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx.Floor(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr));
- var result = Avx.Floor(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx.Floor(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__FloorDouble();
- var result = Avx.Floor(test._fld);
+ var result = Avx.Floor(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__FloorDouble();
+
+ fixed (Vector256<Double>* pFld1 = &test._fld1)
+ {
+ var result = Avx.Floor(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.Floor(_fld);
+ var result = Avx.Floor(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx.Floor(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.Floor(test._fld);
+ var result = Avx.Floor(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.Floor(
+ Avx.LoadVector256((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.Floor)}<Double>(Vector256<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Floor.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Floor.Single.cs
index 38ce287d44..4f797ad84b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Floor.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Floor.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__FloorSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Single> _fld;
+ public Vector256<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__FloorSingle testClass)
{
- var result = Avx.Floor(_fld);
+ var result = Avx.Floor(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__FloorSingle testClass)
+ {
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.Floor(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector256<Single> _clsVar;
+ private static Vector256<Single> _clsVar1;
- private Vector256<Single> _fld;
+ private Vector256<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__FloorSingle()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
}
public SimpleUnaryOpTest__FloorSingle()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.Floor(
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.Floor(
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.Floor(
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.Floor), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.Floor), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.Floor), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.Floor(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.Floor(
+ Avx.LoadVector256((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr);
- var result = Avx.Floor(firstOp);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var result = Avx.Floor(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.Floor(firstOp);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.Floor(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.Floor(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.Floor(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__FloorSingle();
- var result = Avx.Floor(test._fld);
+ var result = Avx.Floor(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__FloorSingle();
+
+ fixed (Vector256<Single>* pFld1 = &test._fld1)
+ {
+ var result = Avx.Floor(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.Floor(_fld);
+ var result = Avx.Floor(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.Floor(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.Floor(test._fld);
+ var result = Avx.Floor(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.Floor(
+ Avx.LoadVector256((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.Floor)}<Single>(Vector256<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Max.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Max.Double.cs
index c2827fab5d..e50022a06c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Max.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Max.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld1;
private Vector256<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var result = Avx.Max(left, right);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var result = Avx.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.Max(left, right);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.Max(left, right);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> left, Vector256<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Max.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Max.Single.cs
index 3832565a38..09c1d15f01 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Max.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Max.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld1;
private Vector256<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var result = Avx.Max(left, right);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var result = Avx.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.Max(left, right);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.Max(left, right);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> left, Vector256<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Min.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Min.Double.cs
index c42b1f56e0..535a1dc447 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Min.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Min.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld1;
private Vector256<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var result = Avx.Min(left, right);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var result = Avx.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.Min(left, right);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.Min(left, right);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> left, Vector256<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Min.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Min.Single.cs
index 07f05ea25a..b0c6db94ff 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Min.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Min.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld1;
private Vector256<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var result = Avx.Min(left, right);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var result = Avx.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.Min(left, right);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.Min(left, right);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> left, Vector256<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Multiply.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Multiply.Double.cs
index a438d7ebea..19f3f5c5c5 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Multiply.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Multiply.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld1;
private Vector256<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var result = Avx.Multiply(left, right);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var result = Avx.Multiply(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.Multiply(left, right);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.Multiply(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.Multiply(left, right);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.Multiply(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> left, Vector256<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Multiply.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Multiply.Single.cs
index 250d817d93..0a878fba51 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Multiply.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Multiply.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplySingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld1;
private Vector256<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplySingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var result = Avx.Multiply(left, right);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var result = Avx.Multiply(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.Multiply(left, right);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.Multiply(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.Multiply(left, right);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.Multiply(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> left, Vector256<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Or.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Or.Double.cs
index 4d634fc9e5..b9b6ec4e48 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Or.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Or.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld1;
private Vector256<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var result = Avx.Or(left, right);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var result = Avx.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.Or(left, right);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.Or(left, right);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> left, Vector256<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Or.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Or.Single.cs
index 109e3e791b..850b577b77 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Or.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Or.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld1;
private Vector256<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var result = Avx.Or(left, right);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var result = Avx.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.Or(left, right);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.Or(left, right);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> left, Vector256<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/PermuteVar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/PermuteVar.Double.cs
index ac0227df71..78f29e7404 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/PermuteVar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/PermuteVar.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__PermuteVarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Int64[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld1;
private Vector256<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__PermuteVarDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)1; }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Int64>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
- var result = Avx.PermuteVar(left, right);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx.PermuteVar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx.PermuteVar(left, right);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx.PermuteVar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx.PermuteVar(left, right);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx.PermuteVar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> left, Vector256<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/PermuteVar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/PermuteVar.Single.cs
index dc437742bc..12116a29f6 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/PermuteVar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/PermuteVar.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__PermuteVarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Int32[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__PermuteVarSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = 1; }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Int32>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx.PermuteVar(left, right);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx.PermuteVar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx.PermuteVar(left, right);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx.PermuteVar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx.PermuteVar(left, right);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx.PermuteVar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundCurrentDirection.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundCurrentDirection.Double.cs
index 37b8312194..800b6c9464 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundCurrentDirection.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundCurrentDirection.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundCurrentDirectionDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Double> _fld;
+ public Vector256<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundCurrentDirectionDouble testClass)
{
- var result = Avx.RoundCurrentDirection(_fld);
+ var result = Avx.RoundCurrentDirection(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundCurrentDirectionDouble testClass)
+ {
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundCurrentDirection(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector256<Double> _clsVar;
+ private static Vector256<Double> _clsVar1;
- private Vector256<Double> _fld;
+ private Vector256<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundCurrentDirectionDouble()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
}
public SimpleUnaryOpTest__RoundCurrentDirectionDouble()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.RoundCurrentDirection(
- Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.RoundCurrentDirection(
- Avx.LoadVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.RoundCurrentDirection(
- Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundCurrentDirection), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundCurrentDirection), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundCurrentDirection), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.RoundCurrentDirection(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.RoundCurrentDirection(
+ Avx.LoadVector256((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr);
- var result = Avx.RoundCurrentDirection(firstOp);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var result = Avx.RoundCurrentDirection(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArrayPtr));
- var result = Avx.RoundCurrentDirection(firstOp);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundCurrentDirection(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr));
- var result = Avx.RoundCurrentDirection(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundCurrentDirection(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundCurrentDirectionDouble();
- var result = Avx.RoundCurrentDirection(test._fld);
+ var result = Avx.RoundCurrentDirection(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundCurrentDirectionDouble();
+
+ fixed (Vector256<Double>* pFld1 = &test._fld1)
+ {
+ var result = Avx.RoundCurrentDirection(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.RoundCurrentDirection(_fld);
+ var result = Avx.RoundCurrentDirection(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundCurrentDirection(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.RoundCurrentDirection(test._fld);
+ var result = Avx.RoundCurrentDirection(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.RoundCurrentDirection(
+ Avx.LoadVector256((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.RoundCurrentDirection)}<Double>(Vector256<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundCurrentDirection.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundCurrentDirection.Single.cs
index 8aa0e7ddf1..94dbdc3c4b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundCurrentDirection.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundCurrentDirection.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundCurrentDirectionSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Single> _fld;
+ public Vector256<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundCurrentDirectionSingle testClass)
{
- var result = Avx.RoundCurrentDirection(_fld);
+ var result = Avx.RoundCurrentDirection(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundCurrentDirectionSingle testClass)
+ {
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundCurrentDirection(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector256<Single> _clsVar;
+ private static Vector256<Single> _clsVar1;
- private Vector256<Single> _fld;
+ private Vector256<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundCurrentDirectionSingle()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
}
public SimpleUnaryOpTest__RoundCurrentDirectionSingle()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.RoundCurrentDirection(
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.RoundCurrentDirection(
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.RoundCurrentDirection(
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundCurrentDirection), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundCurrentDirection), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundCurrentDirection), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.RoundCurrentDirection(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.RoundCurrentDirection(
+ Avx.LoadVector256((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr);
- var result = Avx.RoundCurrentDirection(firstOp);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var result = Avx.RoundCurrentDirection(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.RoundCurrentDirection(firstOp);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundCurrentDirection(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.RoundCurrentDirection(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundCurrentDirection(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundCurrentDirectionSingle();
- var result = Avx.RoundCurrentDirection(test._fld);
+ var result = Avx.RoundCurrentDirection(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundCurrentDirectionSingle();
+
+ fixed (Vector256<Single>* pFld1 = &test._fld1)
+ {
+ var result = Avx.RoundCurrentDirection(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.RoundCurrentDirection(_fld);
+ var result = Avx.RoundCurrentDirection(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundCurrentDirection(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.RoundCurrentDirection(test._fld);
+ var result = Avx.RoundCurrentDirection(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.RoundCurrentDirection(
+ Avx.LoadVector256((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.RoundCurrentDirection)}<Single>(Vector256<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNearestInteger.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNearestInteger.Double.cs
index 3dbc7ea610..0ef1e120b8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNearestInteger.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNearestInteger.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundToNearestIntegerDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Double> _fld;
+ public Vector256<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundToNearestIntegerDouble testClass)
{
- var result = Avx.RoundToNearestInteger(_fld);
+ var result = Avx.RoundToNearestInteger(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundToNearestIntegerDouble testClass)
+ {
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundToNearestInteger(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector256<Double> _clsVar;
+ private static Vector256<Double> _clsVar1;
- private Vector256<Double> _fld;
+ private Vector256<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundToNearestIntegerDouble()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
}
public SimpleUnaryOpTest__RoundToNearestIntegerDouble()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.RoundToNearestInteger(
- Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.RoundToNearestInteger(
- Avx.LoadVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.RoundToNearestInteger(
- Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToNearestInteger), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToNearestInteger), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToNearestInteger), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.RoundToNearestInteger(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.RoundToNearestInteger(
+ Avx.LoadVector256((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr);
- var result = Avx.RoundToNearestInteger(firstOp);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var result = Avx.RoundToNearestInteger(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArrayPtr));
- var result = Avx.RoundToNearestInteger(firstOp);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundToNearestInteger(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr));
- var result = Avx.RoundToNearestInteger(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundToNearestInteger(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundToNearestIntegerDouble();
- var result = Avx.RoundToNearestInteger(test._fld);
+ var result = Avx.RoundToNearestInteger(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundToNearestIntegerDouble();
+
+ fixed (Vector256<Double>* pFld1 = &test._fld1)
+ {
+ var result = Avx.RoundToNearestInteger(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.RoundToNearestInteger(_fld);
+ var result = Avx.RoundToNearestInteger(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundToNearestInteger(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.RoundToNearestInteger(test._fld);
+ var result = Avx.RoundToNearestInteger(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.RoundToNearestInteger(
+ Avx.LoadVector256((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.RoundToNearestInteger)}<Double>(Vector256<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNearestInteger.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNearestInteger.Single.cs
index ec79ee30fa..ac41802e44 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNearestInteger.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNearestInteger.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundToNearestIntegerSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Single> _fld;
+ public Vector256<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundToNearestIntegerSingle testClass)
{
- var result = Avx.RoundToNearestInteger(_fld);
+ var result = Avx.RoundToNearestInteger(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundToNearestIntegerSingle testClass)
+ {
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundToNearestInteger(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector256<Single> _clsVar;
+ private static Vector256<Single> _clsVar1;
- private Vector256<Single> _fld;
+ private Vector256<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundToNearestIntegerSingle()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
}
public SimpleUnaryOpTest__RoundToNearestIntegerSingle()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.RoundToNearestInteger(
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.RoundToNearestInteger(
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.RoundToNearestInteger(
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToNearestInteger), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToNearestInteger), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToNearestInteger), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.RoundToNearestInteger(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.RoundToNearestInteger(
+ Avx.LoadVector256((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr);
- var result = Avx.RoundToNearestInteger(firstOp);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var result = Avx.RoundToNearestInteger(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.RoundToNearestInteger(firstOp);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundToNearestInteger(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.RoundToNearestInteger(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundToNearestInteger(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundToNearestIntegerSingle();
- var result = Avx.RoundToNearestInteger(test._fld);
+ var result = Avx.RoundToNearestInteger(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundToNearestIntegerSingle();
+
+ fixed (Vector256<Single>* pFld1 = &test._fld1)
+ {
+ var result = Avx.RoundToNearestInteger(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.RoundToNearestInteger(_fld);
+ var result = Avx.RoundToNearestInteger(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundToNearestInteger(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.RoundToNearestInteger(test._fld);
+ var result = Avx.RoundToNearestInteger(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.RoundToNearestInteger(
+ Avx.LoadVector256((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.RoundToNearestInteger)}<Single>(Vector256<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNegativeInfinity.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNegativeInfinity.Double.cs
index 7d339e0863..c9c97a59de 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNegativeInfinity.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNegativeInfinity.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundToNegativeInfinityDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Double> _fld;
+ public Vector256<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundToNegativeInfinityDouble testClass)
{
- var result = Avx.RoundToNegativeInfinity(_fld);
+ var result = Avx.RoundToNegativeInfinity(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundToNegativeInfinityDouble testClass)
+ {
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundToNegativeInfinity(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector256<Double> _clsVar;
+ private static Vector256<Double> _clsVar1;
- private Vector256<Double> _fld;
+ private Vector256<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundToNegativeInfinityDouble()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
}
public SimpleUnaryOpTest__RoundToNegativeInfinityDouble()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.RoundToNegativeInfinity(
- Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.RoundToNegativeInfinity(
- Avx.LoadVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.RoundToNegativeInfinity(
- Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToNegativeInfinity), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToNegativeInfinity), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToNegativeInfinity), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.RoundToNegativeInfinity(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.RoundToNegativeInfinity(
+ Avx.LoadVector256((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr);
- var result = Avx.RoundToNegativeInfinity(firstOp);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var result = Avx.RoundToNegativeInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArrayPtr));
- var result = Avx.RoundToNegativeInfinity(firstOp);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundToNegativeInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr));
- var result = Avx.RoundToNegativeInfinity(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundToNegativeInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundToNegativeInfinityDouble();
- var result = Avx.RoundToNegativeInfinity(test._fld);
+ var result = Avx.RoundToNegativeInfinity(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundToNegativeInfinityDouble();
+
+ fixed (Vector256<Double>* pFld1 = &test._fld1)
+ {
+ var result = Avx.RoundToNegativeInfinity(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.RoundToNegativeInfinity(_fld);
+ var result = Avx.RoundToNegativeInfinity(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundToNegativeInfinity(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.RoundToNegativeInfinity(test._fld);
+ var result = Avx.RoundToNegativeInfinity(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.RoundToNegativeInfinity(
+ Avx.LoadVector256((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.RoundToNegativeInfinity)}<Double>(Vector256<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNegativeInfinity.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNegativeInfinity.Single.cs
index 15a370f2ba..36e5b48aa1 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNegativeInfinity.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToNegativeInfinity.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundToNegativeInfinitySingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Single> _fld;
+ public Vector256<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundToNegativeInfinitySingle testClass)
{
- var result = Avx.RoundToNegativeInfinity(_fld);
+ var result = Avx.RoundToNegativeInfinity(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundToNegativeInfinitySingle testClass)
+ {
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundToNegativeInfinity(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector256<Single> _clsVar;
+ private static Vector256<Single> _clsVar1;
- private Vector256<Single> _fld;
+ private Vector256<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundToNegativeInfinitySingle()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
}
public SimpleUnaryOpTest__RoundToNegativeInfinitySingle()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.RoundToNegativeInfinity(
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.RoundToNegativeInfinity(
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.RoundToNegativeInfinity(
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToNegativeInfinity), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToNegativeInfinity), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToNegativeInfinity), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.RoundToNegativeInfinity(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.RoundToNegativeInfinity(
+ Avx.LoadVector256((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr);
- var result = Avx.RoundToNegativeInfinity(firstOp);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var result = Avx.RoundToNegativeInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.RoundToNegativeInfinity(firstOp);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundToNegativeInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.RoundToNegativeInfinity(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundToNegativeInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundToNegativeInfinitySingle();
- var result = Avx.RoundToNegativeInfinity(test._fld);
+ var result = Avx.RoundToNegativeInfinity(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundToNegativeInfinitySingle();
+
+ fixed (Vector256<Single>* pFld1 = &test._fld1)
+ {
+ var result = Avx.RoundToNegativeInfinity(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.RoundToNegativeInfinity(_fld);
+ var result = Avx.RoundToNegativeInfinity(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundToNegativeInfinity(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.RoundToNegativeInfinity(test._fld);
+ var result = Avx.RoundToNegativeInfinity(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.RoundToNegativeInfinity(
+ Avx.LoadVector256((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.RoundToNegativeInfinity)}<Single>(Vector256<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToPositiveInfinity.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToPositiveInfinity.Double.cs
index 13cccda13f..c0837e1ea6 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToPositiveInfinity.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToPositiveInfinity.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundToPositiveInfinityDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Double> _fld;
+ public Vector256<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundToPositiveInfinityDouble testClass)
{
- var result = Avx.RoundToPositiveInfinity(_fld);
+ var result = Avx.RoundToPositiveInfinity(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundToPositiveInfinityDouble testClass)
+ {
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundToPositiveInfinity(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector256<Double> _clsVar;
+ private static Vector256<Double> _clsVar1;
- private Vector256<Double> _fld;
+ private Vector256<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundToPositiveInfinityDouble()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
}
public SimpleUnaryOpTest__RoundToPositiveInfinityDouble()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.RoundToPositiveInfinity(
- Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.RoundToPositiveInfinity(
- Avx.LoadVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.RoundToPositiveInfinity(
- Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToPositiveInfinity), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToPositiveInfinity), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToPositiveInfinity), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.RoundToPositiveInfinity(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.RoundToPositiveInfinity(
+ Avx.LoadVector256((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr);
- var result = Avx.RoundToPositiveInfinity(firstOp);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var result = Avx.RoundToPositiveInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArrayPtr));
- var result = Avx.RoundToPositiveInfinity(firstOp);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundToPositiveInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr));
- var result = Avx.RoundToPositiveInfinity(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundToPositiveInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundToPositiveInfinityDouble();
- var result = Avx.RoundToPositiveInfinity(test._fld);
+ var result = Avx.RoundToPositiveInfinity(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundToPositiveInfinityDouble();
+
+ fixed (Vector256<Double>* pFld1 = &test._fld1)
+ {
+ var result = Avx.RoundToPositiveInfinity(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.RoundToPositiveInfinity(_fld);
+ var result = Avx.RoundToPositiveInfinity(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundToPositiveInfinity(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.RoundToPositiveInfinity(test._fld);
+ var result = Avx.RoundToPositiveInfinity(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.RoundToPositiveInfinity(
+ Avx.LoadVector256((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.RoundToPositiveInfinity)}<Double>(Vector256<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToPositiveInfinity.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToPositiveInfinity.Single.cs
index be55a6e5f0..e25d089177 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToPositiveInfinity.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToPositiveInfinity.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundToPositiveInfinitySingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Single> _fld;
+ public Vector256<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundToPositiveInfinitySingle testClass)
{
- var result = Avx.RoundToPositiveInfinity(_fld);
+ var result = Avx.RoundToPositiveInfinity(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundToPositiveInfinitySingle testClass)
+ {
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundToPositiveInfinity(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector256<Single> _clsVar;
+ private static Vector256<Single> _clsVar1;
- private Vector256<Single> _fld;
+ private Vector256<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundToPositiveInfinitySingle()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
}
public SimpleUnaryOpTest__RoundToPositiveInfinitySingle()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.RoundToPositiveInfinity(
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.RoundToPositiveInfinity(
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.RoundToPositiveInfinity(
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToPositiveInfinity), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToPositiveInfinity), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToPositiveInfinity), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.RoundToPositiveInfinity(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.RoundToPositiveInfinity(
+ Avx.LoadVector256((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr);
- var result = Avx.RoundToPositiveInfinity(firstOp);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var result = Avx.RoundToPositiveInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.RoundToPositiveInfinity(firstOp);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundToPositiveInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.RoundToPositiveInfinity(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundToPositiveInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundToPositiveInfinitySingle();
- var result = Avx.RoundToPositiveInfinity(test._fld);
+ var result = Avx.RoundToPositiveInfinity(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundToPositiveInfinitySingle();
+
+ fixed (Vector256<Single>* pFld1 = &test._fld1)
+ {
+ var result = Avx.RoundToPositiveInfinity(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.RoundToPositiveInfinity(_fld);
+ var result = Avx.RoundToPositiveInfinity(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundToPositiveInfinity(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.RoundToPositiveInfinity(test._fld);
+ var result = Avx.RoundToPositiveInfinity(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.RoundToPositiveInfinity(
+ Avx.LoadVector256((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.RoundToPositiveInfinity)}<Single>(Vector256<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToZero.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToZero.Double.cs
index 3ce5037228..93bd094b63 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToZero.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToZero.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundToZeroDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Double> _fld;
+ public Vector256<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundToZeroDouble testClass)
{
- var result = Avx.RoundToZero(_fld);
+ var result = Avx.RoundToZero(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundToZeroDouble testClass)
+ {
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundToZero(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector256<Double> _clsVar;
+ private static Vector256<Double> _clsVar1;
- private Vector256<Double> _fld;
+ private Vector256<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundToZeroDouble()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
}
public SimpleUnaryOpTest__RoundToZeroDouble()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.RoundToZero(
- Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.RoundToZero(
- Avx.LoadVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.RoundToZero(
- Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToZero), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToZero), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToZero), new Type[] { typeof(Vector256<Double>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.RoundToZero(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.RoundToZero(
+ Avx.LoadVector256((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArrayPtr);
- var result = Avx.RoundToZero(firstOp);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var result = Avx.RoundToZero(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArrayPtr));
- var result = Avx.RoundToZero(firstOp);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundToZero(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArrayPtr));
- var result = Avx.RoundToZero(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundToZero(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundToZeroDouble();
- var result = Avx.RoundToZero(test._fld);
+ var result = Avx.RoundToZero(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundToZeroDouble();
+
+ fixed (Vector256<Double>* pFld1 = &test._fld1)
+ {
+ var result = Avx.RoundToZero(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.RoundToZero(_fld);
+ var result = Avx.RoundToZero(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundToZero(
+ Avx.LoadVector256((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.RoundToZero(test._fld);
+ var result = Avx.RoundToZero(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.RoundToZero(
+ Avx.LoadVector256((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.RoundToZero)}<Double>(Vector256<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToZero.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToZero.Single.cs
index 5010c06109..4064fca72d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToZero.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/RoundToZero.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundToZeroSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector256<Single> _fld;
+ public Vector256<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundToZeroSingle testClass)
{
- var result = Avx.RoundToZero(_fld);
+ var result = Avx.RoundToZero(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundToZeroSingle testClass)
+ {
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundToZero(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector256<Single> _clsVar;
+ private static Vector256<Single> _clsVar1;
- private Vector256<Single> _fld;
+ private Vector256<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundToZeroSingle()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
}
public SimpleUnaryOpTest__RoundToZeroSingle()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx.RoundToZero(
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx.RoundToZero(
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx.RoundToZero(
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToZero), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToZero), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx).GetMethod(nameof(Avx.RoundToZero), new Type[] { typeof(Vector256<Single>) })
.Invoke(null, new object[] {
- Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr))
+ Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx.RoundToZero(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx.RoundToZero(
+ Avx.LoadVector256((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArrayPtr);
- var result = Avx.RoundToZero(firstOp);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var result = Avx.RoundToZero(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.RoundToZero(firstOp);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundToZero(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArrayPtr));
- var result = Avx.RoundToZero(firstOp);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx.RoundToZero(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundToZeroSingle();
- var result = Avx.RoundToZero(test._fld);
+ var result = Avx.RoundToZero(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundToZeroSingle();
+
+ fixed (Vector256<Single>* pFld1 = &test._fld1)
+ {
+ var result = Avx.RoundToZero(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx.RoundToZero(_fld);
+ var result = Avx.RoundToZero(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx.RoundToZero(
+ Avx.LoadVector256((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx.RoundToZero(test._fld);
+ var result = Avx.RoundToZero(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.RoundToZero(
+ Avx.LoadVector256((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.RoundToZero)}<Single>(Vector256<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Subtract.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Subtract.Double.cs
index 7db1ebbbeb..18be113e6d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Subtract.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Subtract.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld1;
private Vector256<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var result = Avx.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var result = Avx.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.Subtract(left, right);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.Subtract(left, right);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> left, Vector256<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Subtract.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Subtract.Single.cs
index 4a2b06efd1..a3d4252e2e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Subtract.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Subtract.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld1;
private Vector256<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var result = Avx.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var result = Avx.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.Subtract(left, right);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.Subtract(left, right);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> left, Vector256<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Byte.cs
index 86540e8a5f..9e386bc3bd 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Byte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestCByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Avx.TestC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestCByte testClass)
+ {
+ fixed (Vector256<Byte>* pFld1 = &_fld1)
+ fixed (Vector256<Byte>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((Byte*)(pFld1)),
+ Avx.LoadVector256((Byte*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld1;
private Vector256<Byte> _fld2;
- private BooleanBinaryOpTest__DataTable<Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestCByte()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Byte, Byte>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Byte>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Byte>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((Byte*)(pClsVar1)),
+ Avx.LoadVector256((Byte*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
- var result = Avx.TestC(left, right);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx.TestC(left, right);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx.TestC(left, right);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestCByte();
+
+ fixed (Vector256<Byte>* pFld1 = &test._fld1)
+ fixed (Vector256<Byte>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((Byte*)(pFld1)),
+ Avx.LoadVector256((Byte*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Byte>* pFld1 = &_fld1)
+ fixed (Vector256<Byte>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((Byte*)(pFld1)),
+ Avx.LoadVector256((Byte*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestC(
+ Avx.LoadVector256((Byte*)(&test._fld1)),
+ Avx.LoadVector256((Byte*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<Byte> op2, bool result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Byte[] left, Byte[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestC)}<Byte>(Vector256<Byte>, Vector256<Byte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Int16.cs
index b4c601ab99..e9949abdd2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Int16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestCInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Avx.TestC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestCInt16 testClass)
+ {
+ fixed (Vector256<Int16>* pFld1 = &_fld1)
+ fixed (Vector256<Int16>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((Int16*)(pFld1)),
+ Avx.LoadVector256((Int16*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private BooleanBinaryOpTest__DataTable<Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestCInt16()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Int16, Int16>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Int16>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Int16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((Int16*)(pClsVar1)),
+ Avx.LoadVector256((Int16*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx.TestC(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx.TestC(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx.TestC(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestCInt16();
+
+ fixed (Vector256<Int16>* pFld1 = &test._fld1)
+ fixed (Vector256<Int16>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((Int16*)(pFld1)),
+ Avx.LoadVector256((Int16*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Int16>* pFld1 = &_fld1)
+ fixed (Vector256<Int16>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((Int16*)(pFld1)),
+ Avx.LoadVector256((Int16*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestC(
+ Avx.LoadVector256((Int16*)(&test._fld1)),
+ Avx.LoadVector256((Int16*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, bool result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int16[] left, Int16[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestC)}<Int16>(Vector256<Int16>, Vector256<Int16>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Int32.cs
index 86989640a6..44637a581a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Int32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestCInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Avx.TestC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestCInt32 testClass)
+ {
+ fixed (Vector256<Int32>* pFld1 = &_fld1)
+ fixed (Vector256<Int32>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((Int32*)(pFld1)),
+ Avx.LoadVector256((Int32*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private BooleanBinaryOpTest__DataTable<Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestCInt32()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Int32, Int32>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Int32>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Int32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((Int32*)(pClsVar1)),
+ Avx.LoadVector256((Int32*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx.TestC(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx.TestC(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx.TestC(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestCInt32();
+
+ fixed (Vector256<Int32>* pFld1 = &test._fld1)
+ fixed (Vector256<Int32>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((Int32*)(pFld1)),
+ Avx.LoadVector256((Int32*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Int32>* pFld1 = &_fld1)
+ fixed (Vector256<Int32>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((Int32*)(pFld1)),
+ Avx.LoadVector256((Int32*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestC(
+ Avx.LoadVector256((Int32*)(&test._fld1)),
+ Avx.LoadVector256((Int32*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, bool result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int32[] left, Int32[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestC)}<Int32>(Vector256<Int32>, Vector256<Int32>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Int64.cs
index 90d1242971..8fcde0853e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.Int64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestCInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int64> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Avx.TestC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestCInt64 testClass)
+ {
+ fixed (Vector256<Int64>* pFld1 = &_fld1)
+ fixed (Vector256<Int64>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((Int64*)(pFld1)),
+ Avx.LoadVector256((Int64*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int64> _fld1;
private Vector256<Int64> _fld2;
- private BooleanBinaryOpTest__DataTable<Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestCInt64()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Int64, Int64>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Int64>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Int64>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((Int64*)(pClsVar1)),
+ Avx.LoadVector256((Int64*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
- var result = Avx.TestC(left, right);
+ var op1 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx.TestC(left, right);
+ var op1 = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx.TestC(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestCInt64();
+
+ fixed (Vector256<Int64>* pFld1 = &test._fld1)
+ fixed (Vector256<Int64>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((Int64*)(pFld1)),
+ Avx.LoadVector256((Int64*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Int64>* pFld1 = &_fld1)
+ fixed (Vector256<Int64>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((Int64*)(pFld1)),
+ Avx.LoadVector256((Int64*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestC(
+ Avx.LoadVector256((Int64*)(&test._fld1)),
+ Avx.LoadVector256((Int64*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int64> left, Vector256<Int64> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int64> op1, Vector256<Int64> op2, bool result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int64[] left, Int64[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestC)}<Int64>(Vector256<Int64>, Vector256<Int64>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.SByte.cs
index ebcbc6f581..ccbc89f850 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.SByte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestCSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<SByte> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Avx.TestC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestCSByte testClass)
+ {
+ fixed (Vector256<SByte>* pFld1 = &_fld1)
+ fixed (Vector256<SByte>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((SByte*)(pFld1)),
+ Avx.LoadVector256((SByte*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<SByte> _fld1;
private Vector256<SByte> _fld2;
- private BooleanBinaryOpTest__DataTable<SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestCSByte()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<SByte, SByte>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<SByte>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<SByte>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((SByte*)(pClsVar1)),
+ Avx.LoadVector256((SByte*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var result = Avx.TestC(left, right);
+ var op1 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx.TestC(left, right);
+ var op1 = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx.TestC(left, right);
+ var op1 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestCSByte();
+
+ fixed (Vector256<SByte>* pFld1 = &test._fld1)
+ fixed (Vector256<SByte>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((SByte*)(pFld1)),
+ Avx.LoadVector256((SByte*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<SByte>* pFld1 = &_fld1)
+ fixed (Vector256<SByte>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((SByte*)(pFld1)),
+ Avx.LoadVector256((SByte*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestC(
+ Avx.LoadVector256((SByte*)(&test._fld1)),
+ Avx.LoadVector256((SByte*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<SByte> op1, Vector256<SByte> op2, bool result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(SByte[] left, SByte[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestC)}<SByte>(Vector256<SByte>, Vector256<SByte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.UInt16.cs
index 8b3abb0116..102a6ae8f6 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.UInt16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestCUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt16> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Avx.TestC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestCUInt16 testClass)
+ {
+ fixed (Vector256<UInt16>* pFld1 = &_fld1)
+ fixed (Vector256<UInt16>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((UInt16*)(pFld1)),
+ Avx.LoadVector256((UInt16*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt16> _fld1;
private Vector256<UInt16> _fld2;
- private BooleanBinaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestCUInt16()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<UInt16, UInt16>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<UInt16>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<UInt16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((UInt16*)(pClsVar1)),
+ Avx.LoadVector256((UInt16*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
- var result = Avx.TestC(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx.TestC(left, right);
+ var op1 = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx.TestC(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestCUInt16();
+
+ fixed (Vector256<UInt16>* pFld1 = &test._fld1)
+ fixed (Vector256<UInt16>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((UInt16*)(pFld1)),
+ Avx.LoadVector256((UInt16*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<UInt16>* pFld1 = &_fld1)
+ fixed (Vector256<UInt16>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((UInt16*)(pFld1)),
+ Avx.LoadVector256((UInt16*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestC(
+ Avx.LoadVector256((UInt16*)(&test._fld1)),
+ Avx.LoadVector256((UInt16*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt16> op1, Vector256<UInt16> op2, bool result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt16[] left, UInt16[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestC)}<UInt16>(Vector256<UInt16>, Vector256<UInt16>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.UInt32.cs
index d61d540c15..033ad221fc 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.UInt32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestCUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt32> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Avx.TestC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestCUInt32 testClass)
+ {
+ fixed (Vector256<UInt32>* pFld1 = &_fld1)
+ fixed (Vector256<UInt32>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((UInt32*)(pFld1)),
+ Avx.LoadVector256((UInt32*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt32> _fld1;
private Vector256<UInt32> _fld2;
- private BooleanBinaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestCUInt32()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<UInt32, UInt32>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<UInt32>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<UInt32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((UInt32*)(pClsVar1)),
+ Avx.LoadVector256((UInt32*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
- var result = Avx.TestC(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx.TestC(left, right);
+ var op1 = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx.TestC(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestCUInt32();
+
+ fixed (Vector256<UInt32>* pFld1 = &test._fld1)
+ fixed (Vector256<UInt32>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((UInt32*)(pFld1)),
+ Avx.LoadVector256((UInt32*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<UInt32>* pFld1 = &_fld1)
+ fixed (Vector256<UInt32>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((UInt32*)(pFld1)),
+ Avx.LoadVector256((UInt32*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestC(
+ Avx.LoadVector256((UInt32*)(&test._fld1)),
+ Avx.LoadVector256((UInt32*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt32> left, Vector256<UInt32> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt32> op1, Vector256<UInt32> op2, bool result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt32[] left, UInt32[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestC)}<UInt32>(Vector256<UInt32>, Vector256<UInt32>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.UInt64.cs
index 10fbd839fb..307b13ffb6 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestC.UInt64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestCUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt64> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Avx.TestC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestCUInt64 testClass)
+ {
+ fixed (Vector256<UInt64>* pFld1 = &_fld1)
+ fixed (Vector256<UInt64>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((UInt64*)(pFld1)),
+ Avx.LoadVector256((UInt64*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt64> _fld1;
private Vector256<UInt64> _fld2;
- private BooleanBinaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestCUInt64()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<UInt64, UInt64>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestC), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<UInt64>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<UInt64>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((UInt64*)(pClsVar1)),
+ Avx.LoadVector256((UInt64*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
- var result = Avx.TestC(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx.TestC(left, right);
+ var op1 = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx.TestC(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestCUInt64();
+
+ fixed (Vector256<UInt64>* pFld1 = &test._fld1)
+ fixed (Vector256<UInt64>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((UInt64*)(pFld1)),
+ Avx.LoadVector256((UInt64*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<UInt64>* pFld1 = &_fld1)
+ fixed (Vector256<UInt64>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestC(
+ Avx.LoadVector256((UInt64*)(pFld1)),
+ Avx.LoadVector256((UInt64*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestC(
+ Avx.LoadVector256((UInt64*)(&test._fld1)),
+ Avx.LoadVector256((UInt64*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt64> left, Vector256<UInt64> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt64> op1, Vector256<UInt64> op2, bool result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt64[] left, UInt64[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestC)}<UInt64>(Vector256<UInt64>, Vector256<UInt64>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Byte.cs
index 9a5dedf7e8..ad709b29d0 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Byte.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestNotZAndNotCByte()
{
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCByte();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCByte();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestNotZAndNotCByte
+ public sealed unsafe class BooleanBinaryOpTest__TestNotZAndNotCByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestNotZAndNotCByte testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestNotZAndNotCByte testClass)
{
var result = Avx.TestNotZAndNotC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestNotZAndNotCByte testClass)
+ {
+ fixed (Vector256<Byte>* pFld1 = &_fld1)
+ fixed (Vector256<Byte>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Byte*)(pFld1)),
+ Avx.LoadVector256((Byte*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld1;
private Vector256<Byte> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<Byte, Byte> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestNotZAndNotCByte()
+ static BooleanBinaryOpTest__TestNotZAndNotCByte()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Byte>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Byte>>());
}
- public BooleanTwoComparisonOpTest__TestNotZAndNotCByte()
+ public BooleanBinaryOpTest__TestNotZAndNotCByte()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<Byte, Byte>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Byte>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Byte>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Byte*)(pClsVar1)),
+ Avx.LoadVector256((Byte*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCByte();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCByte();
var result = Avx.TestNotZAndNotC(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCByte();
+
+ fixed (Vector256<Byte>* pFld1 = &test._fld1)
+ fixed (Vector256<Byte>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Byte*)(pFld1)),
+ Avx.LoadVector256((Byte*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Byte>* pFld1 = &_fld1)
+ fixed (Vector256<Byte>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Byte*)(pFld1)),
+ Avx.LoadVector256((Byte*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Byte*)(&test._fld1)),
+ Avx.LoadVector256((Byte*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<Byte> op2, bool result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Byte[] left, Byte[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestNotZAndNotC)}<Byte>(Vector256<Byte>, Vector256<Byte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Int16.cs
index bd819d7e0b..52b0342897 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Int16.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestNotZAndNotCInt16()
{
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCInt16();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt16();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestNotZAndNotCInt16
+ public sealed unsafe class BooleanBinaryOpTest__TestNotZAndNotCInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestNotZAndNotCInt16 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestNotZAndNotCInt16 testClass)
{
var result = Avx.TestNotZAndNotC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestNotZAndNotCInt16 testClass)
+ {
+ fixed (Vector256<Int16>* pFld1 = &_fld1)
+ fixed (Vector256<Int16>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Int16*)(pFld1)),
+ Avx.LoadVector256((Int16*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<Int16, Int16> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestNotZAndNotCInt16()
+ static BooleanBinaryOpTest__TestNotZAndNotCInt16()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Int16>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Int16>>());
}
- public BooleanTwoComparisonOpTest__TestNotZAndNotCInt16()
+ public BooleanBinaryOpTest__TestNotZAndNotCInt16()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<Int16, Int16>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Int16>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Int16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Int16*)(pClsVar1)),
+ Avx.LoadVector256((Int16*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCInt16();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt16();
var result = Avx.TestNotZAndNotC(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt16();
+
+ fixed (Vector256<Int16>* pFld1 = &test._fld1)
+ fixed (Vector256<Int16>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Int16*)(pFld1)),
+ Avx.LoadVector256((Int16*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Int16>* pFld1 = &_fld1)
+ fixed (Vector256<Int16>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Int16*)(pFld1)),
+ Avx.LoadVector256((Int16*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Int16*)(&test._fld1)),
+ Avx.LoadVector256((Int16*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, bool result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int16[] left, Int16[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestNotZAndNotC)}<Int16>(Vector256<Int16>, Vector256<Int16>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Int32.cs
index 41347cdbdb..3bf11eda64 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Int32.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestNotZAndNotCInt32()
{
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCInt32();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt32();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestNotZAndNotCInt32
+ public sealed unsafe class BooleanBinaryOpTest__TestNotZAndNotCInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestNotZAndNotCInt32 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestNotZAndNotCInt32 testClass)
{
var result = Avx.TestNotZAndNotC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestNotZAndNotCInt32 testClass)
+ {
+ fixed (Vector256<Int32>* pFld1 = &_fld1)
+ fixed (Vector256<Int32>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Int32*)(pFld1)),
+ Avx.LoadVector256((Int32*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<Int32, Int32> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestNotZAndNotCInt32()
+ static BooleanBinaryOpTest__TestNotZAndNotCInt32()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Int32>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Int32>>());
}
- public BooleanTwoComparisonOpTest__TestNotZAndNotCInt32()
+ public BooleanBinaryOpTest__TestNotZAndNotCInt32()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<Int32, Int32>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Int32>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Int32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Int32*)(pClsVar1)),
+ Avx.LoadVector256((Int32*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCInt32();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt32();
var result = Avx.TestNotZAndNotC(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt32();
+
+ fixed (Vector256<Int32>* pFld1 = &test._fld1)
+ fixed (Vector256<Int32>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Int32*)(pFld1)),
+ Avx.LoadVector256((Int32*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Int32>* pFld1 = &_fld1)
+ fixed (Vector256<Int32>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Int32*)(pFld1)),
+ Avx.LoadVector256((Int32*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Int32*)(&test._fld1)),
+ Avx.LoadVector256((Int32*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, bool result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int32[] left, Int32[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestNotZAndNotC)}<Int32>(Vector256<Int32>, Vector256<Int32>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Int64.cs
index 4ddbea27e3..ebb8264dad 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.Int64.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestNotZAndNotCInt64()
{
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCInt64();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt64();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestNotZAndNotCInt64
+ public sealed unsafe class BooleanBinaryOpTest__TestNotZAndNotCInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int64> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestNotZAndNotCInt64 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestNotZAndNotCInt64 testClass)
{
var result = Avx.TestNotZAndNotC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestNotZAndNotCInt64 testClass)
+ {
+ fixed (Vector256<Int64>* pFld1 = &_fld1)
+ fixed (Vector256<Int64>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Int64*)(pFld1)),
+ Avx.LoadVector256((Int64*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int64> _fld1;
private Vector256<Int64> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<Int64, Int64> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestNotZAndNotCInt64()
+ static BooleanBinaryOpTest__TestNotZAndNotCInt64()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<Int64>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Int64>>());
}
- public BooleanTwoComparisonOpTest__TestNotZAndNotCInt64()
+ public BooleanBinaryOpTest__TestNotZAndNotCInt64()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<Int64, Int64>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Int64>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Int64>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Int64*)(pClsVar1)),
+ Avx.LoadVector256((Int64*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCInt64();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt64();
var result = Avx.TestNotZAndNotC(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt64();
+
+ fixed (Vector256<Int64>* pFld1 = &test._fld1)
+ fixed (Vector256<Int64>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Int64*)(pFld1)),
+ Avx.LoadVector256((Int64*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Int64>* pFld1 = &_fld1)
+ fixed (Vector256<Int64>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Int64*)(pFld1)),
+ Avx.LoadVector256((Int64*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((Int64*)(&test._fld1)),
+ Avx.LoadVector256((Int64*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int64> left, Vector256<Int64> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int64> op1, Vector256<Int64> op2, bool result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int64[] left, Int64[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestNotZAndNotC)}<Int64>(Vector256<Int64>, Vector256<Int64>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.SByte.cs
index 8d0cc39f51..e5fe7fa0d2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.SByte.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestNotZAndNotCSByte()
{
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCSByte();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCSByte();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestNotZAndNotCSByte
+ public sealed unsafe class BooleanBinaryOpTest__TestNotZAndNotCSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<SByte> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestNotZAndNotCSByte testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestNotZAndNotCSByte testClass)
{
var result = Avx.TestNotZAndNotC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestNotZAndNotCSByte testClass)
+ {
+ fixed (Vector256<SByte>* pFld1 = &_fld1)
+ fixed (Vector256<SByte>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((SByte*)(pFld1)),
+ Avx.LoadVector256((SByte*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<SByte> _fld1;
private Vector256<SByte> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<SByte, SByte> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestNotZAndNotCSByte()
+ static BooleanBinaryOpTest__TestNotZAndNotCSByte()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<SByte>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<SByte>>());
}
- public BooleanTwoComparisonOpTest__TestNotZAndNotCSByte()
+ public BooleanBinaryOpTest__TestNotZAndNotCSByte()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<SByte, SByte>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<SByte>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<SByte>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((SByte*)(pClsVar1)),
+ Avx.LoadVector256((SByte*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCSByte();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCSByte();
var result = Avx.TestNotZAndNotC(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCSByte();
+
+ fixed (Vector256<SByte>* pFld1 = &test._fld1)
+ fixed (Vector256<SByte>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((SByte*)(pFld1)),
+ Avx.LoadVector256((SByte*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<SByte>* pFld1 = &_fld1)
+ fixed (Vector256<SByte>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((SByte*)(pFld1)),
+ Avx.LoadVector256((SByte*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((SByte*)(&test._fld1)),
+ Avx.LoadVector256((SByte*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<SByte> op1, Vector256<SByte> op2, bool result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(SByte[] left, SByte[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestNotZAndNotC)}<SByte>(Vector256<SByte>, Vector256<SByte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.UInt16.cs
index b8cb5592de..bd53785740 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.UInt16.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestNotZAndNotCUInt16()
{
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCUInt16();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt16();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestNotZAndNotCUInt16
+ public sealed unsafe class BooleanBinaryOpTest__TestNotZAndNotCUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt16> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestNotZAndNotCUInt16 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestNotZAndNotCUInt16 testClass)
{
var result = Avx.TestNotZAndNotC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestNotZAndNotCUInt16 testClass)
+ {
+ fixed (Vector256<UInt16>* pFld1 = &_fld1)
+ fixed (Vector256<UInt16>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((UInt16*)(pFld1)),
+ Avx.LoadVector256((UInt16*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt16> _fld1;
private Vector256<UInt16> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestNotZAndNotCUInt16()
+ static BooleanBinaryOpTest__TestNotZAndNotCUInt16()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
}
- public BooleanTwoComparisonOpTest__TestNotZAndNotCUInt16()
+ public BooleanBinaryOpTest__TestNotZAndNotCUInt16()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<UInt16, UInt16>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<UInt16>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<UInt16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((UInt16*)(pClsVar1)),
+ Avx.LoadVector256((UInt16*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCUInt16();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt16();
var result = Avx.TestNotZAndNotC(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt16();
+
+ fixed (Vector256<UInt16>* pFld1 = &test._fld1)
+ fixed (Vector256<UInt16>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((UInt16*)(pFld1)),
+ Avx.LoadVector256((UInt16*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<UInt16>* pFld1 = &_fld1)
+ fixed (Vector256<UInt16>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((UInt16*)(pFld1)),
+ Avx.LoadVector256((UInt16*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((UInt16*)(&test._fld1)),
+ Avx.LoadVector256((UInt16*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt16> op1, Vector256<UInt16> op2, bool result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt16[] left, UInt16[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestNotZAndNotC)}<UInt16>(Vector256<UInt16>, Vector256<UInt16>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.UInt32.cs
index cee7a3f426..c8529d6635 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.UInt32.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestNotZAndNotCUInt32()
{
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCUInt32();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt32();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestNotZAndNotCUInt32
+ public sealed unsafe class BooleanBinaryOpTest__TestNotZAndNotCUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt32> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestNotZAndNotCUInt32 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestNotZAndNotCUInt32 testClass)
{
var result = Avx.TestNotZAndNotC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestNotZAndNotCUInt32 testClass)
+ {
+ fixed (Vector256<UInt32>* pFld1 = &_fld1)
+ fixed (Vector256<UInt32>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((UInt32*)(pFld1)),
+ Avx.LoadVector256((UInt32*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt32> _fld1;
private Vector256<UInt32> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestNotZAndNotCUInt32()
+ static BooleanBinaryOpTest__TestNotZAndNotCUInt32()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
}
- public BooleanTwoComparisonOpTest__TestNotZAndNotCUInt32()
+ public BooleanBinaryOpTest__TestNotZAndNotCUInt32()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<UInt32, UInt32>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<UInt32>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<UInt32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((UInt32*)(pClsVar1)),
+ Avx.LoadVector256((UInt32*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCUInt32();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt32();
var result = Avx.TestNotZAndNotC(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt32();
+
+ fixed (Vector256<UInt32>* pFld1 = &test._fld1)
+ fixed (Vector256<UInt32>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((UInt32*)(pFld1)),
+ Avx.LoadVector256((UInt32*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<UInt32>* pFld1 = &_fld1)
+ fixed (Vector256<UInt32>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((UInt32*)(pFld1)),
+ Avx.LoadVector256((UInt32*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((UInt32*)(&test._fld1)),
+ Avx.LoadVector256((UInt32*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt32> left, Vector256<UInt32> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt32> op1, Vector256<UInt32> op2, bool result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt32[] left, UInt32[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestNotZAndNotC)}<UInt32>(Vector256<UInt32>, Vector256<UInt32>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.UInt64.cs
index 09df706038..8d89fa4766 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestNotZAndNotC.UInt64.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestNotZAndNotCUInt64()
{
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCUInt64();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt64();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestNotZAndNotCUInt64
+ public sealed unsafe class BooleanBinaryOpTest__TestNotZAndNotCUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt64> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestNotZAndNotCUInt64 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestNotZAndNotCUInt64 testClass)
{
var result = Avx.TestNotZAndNotC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestNotZAndNotCUInt64 testClass)
+ {
+ fixed (Vector256<UInt64>* pFld1 = &_fld1)
+ fixed (Vector256<UInt64>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((UInt64*)(pFld1)),
+ Avx.LoadVector256((UInt64*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt64> _fld1;
private Vector256<UInt64> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestNotZAndNotCUInt64()
+ static BooleanBinaryOpTest__TestNotZAndNotCUInt64()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
}
- public BooleanTwoComparisonOpTest__TestNotZAndNotCUInt64()
+ public BooleanBinaryOpTest__TestNotZAndNotCUInt64()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<UInt64, UInt64>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestNotZAndNotC), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<UInt64>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<UInt64>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((UInt64*)(pClsVar1)),
+ Avx.LoadVector256((UInt64*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx.TestNotZAndNotC(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCUInt64();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt64();
var result = Avx.TestNotZAndNotC(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt64();
+
+ fixed (Vector256<UInt64>* pFld1 = &test._fld1)
+ fixed (Vector256<UInt64>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((UInt64*)(pFld1)),
+ Avx.LoadVector256((UInt64*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<UInt64>* pFld1 = &_fld1)
+ fixed (Vector256<UInt64>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((UInt64*)(pFld1)),
+ Avx.LoadVector256((UInt64*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestNotZAndNotC(
+ Avx.LoadVector256((UInt64*)(&test._fld1)),
+ Avx.LoadVector256((UInt64*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt64> left, Vector256<UInt64> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt64> op1, Vector256<UInt64> op2, bool result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt64[] left, UInt64[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestNotZAndNotC)}<UInt64>(Vector256<UInt64>, Vector256<UInt64>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Byte.cs
index 7ad9303603..2e540ec828 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Byte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestZByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Avx.TestZ(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestZByte testClass)
+ {
+ fixed (Vector256<Byte>* pFld1 = &_fld1)
+ fixed (Vector256<Byte>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Byte*)(pFld1)),
+ Avx.LoadVector256((Byte*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld1;
private Vector256<Byte> _fld2;
- private BooleanBinaryOpTest__DataTable<Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestZByte()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Byte, Byte>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Byte>), typeof(Vector256<Byte>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Byte>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Byte>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Byte*)(pClsVar1)),
+ Avx.LoadVector256((Byte*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
- var result = Avx.TestZ(left, right);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx.TestZ(left, right);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx.TestZ(left, right);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestZByte();
+
+ fixed (Vector256<Byte>* pFld1 = &test._fld1)
+ fixed (Vector256<Byte>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Byte*)(pFld1)),
+ Avx.LoadVector256((Byte*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Byte>* pFld1 = &_fld1)
+ fixed (Vector256<Byte>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Byte*)(pFld1)),
+ Avx.LoadVector256((Byte*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Byte*)(&test._fld1)),
+ Avx.LoadVector256((Byte*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<Byte> op2, bool result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Byte[] left, Byte[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestZ)}<Byte>(Vector256<Byte>, Vector256<Byte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Int16.cs
index 07ca6aeb50..07bc80cb88 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Int16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestZInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Avx.TestZ(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestZInt16 testClass)
+ {
+ fixed (Vector256<Int16>* pFld1 = &_fld1)
+ fixed (Vector256<Int16>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Int16*)(pFld1)),
+ Avx.LoadVector256((Int16*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private BooleanBinaryOpTest__DataTable<Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestZInt16()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Int16, Int16>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int16>), typeof(Vector256<Int16>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Int16>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Int16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Int16*)(pClsVar1)),
+ Avx.LoadVector256((Int16*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx.TestZ(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx.TestZ(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx.TestZ(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestZInt16();
+
+ fixed (Vector256<Int16>* pFld1 = &test._fld1)
+ fixed (Vector256<Int16>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Int16*)(pFld1)),
+ Avx.LoadVector256((Int16*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Int16>* pFld1 = &_fld1)
+ fixed (Vector256<Int16>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Int16*)(pFld1)),
+ Avx.LoadVector256((Int16*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Int16*)(&test._fld1)),
+ Avx.LoadVector256((Int16*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, bool result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int16[] left, Int16[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestZ)}<Int16>(Vector256<Int16>, Vector256<Int16>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Int32.cs
index 770ffc3444..75e4a6cb52 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Int32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestZInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Avx.TestZ(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestZInt32 testClass)
+ {
+ fixed (Vector256<Int32>* pFld1 = &_fld1)
+ fixed (Vector256<Int32>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Int32*)(pFld1)),
+ Avx.LoadVector256((Int32*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private BooleanBinaryOpTest__DataTable<Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestZInt32()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Int32, Int32>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int32>), typeof(Vector256<Int32>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Int32>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Int32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Int32*)(pClsVar1)),
+ Avx.LoadVector256((Int32*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx.TestZ(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx.TestZ(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx.TestZ(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestZInt32();
+
+ fixed (Vector256<Int32>* pFld1 = &test._fld1)
+ fixed (Vector256<Int32>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Int32*)(pFld1)),
+ Avx.LoadVector256((Int32*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Int32>* pFld1 = &_fld1)
+ fixed (Vector256<Int32>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Int32*)(pFld1)),
+ Avx.LoadVector256((Int32*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Int32*)(&test._fld1)),
+ Avx.LoadVector256((Int32*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, bool result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int32[] left, Int32[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestZ)}<Int32>(Vector256<Int32>, Vector256<Int32>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Int64.cs
index 1983047589..e4f5b66c9f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.Int64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestZInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int64> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Avx.TestZ(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestZInt64 testClass)
+ {
+ fixed (Vector256<Int64>* pFld1 = &_fld1)
+ fixed (Vector256<Int64>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Int64*)(pFld1)),
+ Avx.LoadVector256((Int64*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int64> _fld1;
private Vector256<Int64> _fld2;
- private BooleanBinaryOpTest__DataTable<Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestZInt64()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Int64, Int64>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<Int64>), typeof(Vector256<Int64>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Int64>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Int64>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Int64*)(pClsVar1)),
+ Avx.LoadVector256((Int64*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
- var result = Avx.TestZ(left, right);
+ var op1 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx.TestZ(left, right);
+ var op1 = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx.TestZ(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestZInt64();
+
+ fixed (Vector256<Int64>* pFld1 = &test._fld1)
+ fixed (Vector256<Int64>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Int64*)(pFld1)),
+ Avx.LoadVector256((Int64*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Int64>* pFld1 = &_fld1)
+ fixed (Vector256<Int64>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Int64*)(pFld1)),
+ Avx.LoadVector256((Int64*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestZ(
+ Avx.LoadVector256((Int64*)(&test._fld1)),
+ Avx.LoadVector256((Int64*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int64> left, Vector256<Int64> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int64> op1, Vector256<Int64> op2, bool result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int64[] left, Int64[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestZ)}<Int64>(Vector256<Int64>, Vector256<Int64>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.SByte.cs
index 90415ed31b..31d0c23454 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.SByte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestZSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<SByte> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Avx.TestZ(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestZSByte testClass)
+ {
+ fixed (Vector256<SByte>* pFld1 = &_fld1)
+ fixed (Vector256<SByte>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((SByte*)(pFld1)),
+ Avx.LoadVector256((SByte*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<SByte> _fld1;
private Vector256<SByte> _fld2;
- private BooleanBinaryOpTest__DataTable<SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestZSByte()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<SByte, SByte>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<SByte>), typeof(Vector256<SByte>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<SByte>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<SByte>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((SByte*)(pClsVar1)),
+ Avx.LoadVector256((SByte*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var result = Avx.TestZ(left, right);
+ var op1 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx.TestZ(left, right);
+ var op1 = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx.TestZ(left, right);
+ var op1 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestZSByte();
+
+ fixed (Vector256<SByte>* pFld1 = &test._fld1)
+ fixed (Vector256<SByte>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((SByte*)(pFld1)),
+ Avx.LoadVector256((SByte*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<SByte>* pFld1 = &_fld1)
+ fixed (Vector256<SByte>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((SByte*)(pFld1)),
+ Avx.LoadVector256((SByte*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestZ(
+ Avx.LoadVector256((SByte*)(&test._fld1)),
+ Avx.LoadVector256((SByte*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<SByte> op1, Vector256<SByte> op2, bool result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(SByte[] left, SByte[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestZ)}<SByte>(Vector256<SByte>, Vector256<SByte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.UInt16.cs
index 9e18b76619..24cfb6b594 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.UInt16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestZUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt16> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Avx.TestZ(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestZUInt16 testClass)
+ {
+ fixed (Vector256<UInt16>* pFld1 = &_fld1)
+ fixed (Vector256<UInt16>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((UInt16*)(pFld1)),
+ Avx.LoadVector256((UInt16*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt16> _fld1;
private Vector256<UInt16> _fld2;
- private BooleanBinaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestZUInt16()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<UInt16, UInt16>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt16>), typeof(Vector256<UInt16>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<UInt16>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<UInt16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((UInt16*)(pClsVar1)),
+ Avx.LoadVector256((UInt16*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
- var result = Avx.TestZ(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx.TestZ(left, right);
+ var op1 = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx.TestZ(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestZUInt16();
+
+ fixed (Vector256<UInt16>* pFld1 = &test._fld1)
+ fixed (Vector256<UInt16>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((UInt16*)(pFld1)),
+ Avx.LoadVector256((UInt16*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<UInt16>* pFld1 = &_fld1)
+ fixed (Vector256<UInt16>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((UInt16*)(pFld1)),
+ Avx.LoadVector256((UInt16*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestZ(
+ Avx.LoadVector256((UInt16*)(&test._fld1)),
+ Avx.LoadVector256((UInt16*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt16> op1, Vector256<UInt16> op2, bool result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt16[] left, UInt16[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestZ)}<UInt16>(Vector256<UInt16>, Vector256<UInt16>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.UInt32.cs
index d83945e3ea..04c8db1ecc 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.UInt32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestZUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt32> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Avx.TestZ(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestZUInt32 testClass)
+ {
+ fixed (Vector256<UInt32>* pFld1 = &_fld1)
+ fixed (Vector256<UInt32>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((UInt32*)(pFld1)),
+ Avx.LoadVector256((UInt32*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt32> _fld1;
private Vector256<UInt32> _fld2;
- private BooleanBinaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestZUInt32()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<UInt32, UInt32>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt32>), typeof(Vector256<UInt32>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<UInt32>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<UInt32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((UInt32*)(pClsVar1)),
+ Avx.LoadVector256((UInt32*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
- var result = Avx.TestZ(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx.TestZ(left, right);
+ var op1 = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx.TestZ(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestZUInt32();
+
+ fixed (Vector256<UInt32>* pFld1 = &test._fld1)
+ fixed (Vector256<UInt32>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((UInt32*)(pFld1)),
+ Avx.LoadVector256((UInt32*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<UInt32>* pFld1 = &_fld1)
+ fixed (Vector256<UInt32>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((UInt32*)(pFld1)),
+ Avx.LoadVector256((UInt32*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestZ(
+ Avx.LoadVector256((UInt32*)(&test._fld1)),
+ Avx.LoadVector256((UInt32*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt32> left, Vector256<UInt32> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt32> op1, Vector256<UInt32> op2, bool result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt32[] left, UInt32[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestZ)}<UInt32>(Vector256<UInt32>, Vector256<UInt32>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.UInt64.cs
index 45e263c6a0..78d9307789 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/TestZ.UInt64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestZUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt64> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Avx.TestZ(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestZUInt64 testClass)
+ {
+ fixed (Vector256<UInt64>* pFld1 = &_fld1)
+ fixed (Vector256<UInt64>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((UInt64*)(pFld1)),
+ Avx.LoadVector256((UInt64*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt64> _fld1;
private Vector256<UInt64> _fld2;
- private BooleanBinaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestZUInt64()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<UInt64, UInt64>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) })
+ .Invoke(null, new object[] {
Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr)),
Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Avx).GetMethod(nameof(Avx.TestZ), new Type[] { typeof(Vector256<UInt64>), typeof(Vector256<UInt64>) })
+ .Invoke(null, new object[] {
Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr)),
Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<UInt64>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<UInt64>* pClsVar2 = &_clsVar2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((UInt64*)(pClsVar1)),
+ Avx.LoadVector256((UInt64*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
- var result = Avx.TestZ(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx.TestZ(left, right);
+ var op1 = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx.TestZ(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestZUInt64();
+
+ fixed (Vector256<UInt64>* pFld1 = &test._fld1)
+ fixed (Vector256<UInt64>* pFld2 = &test._fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((UInt64*)(pFld1)),
+ Avx.LoadVector256((UInt64*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<UInt64>* pFld1 = &_fld1)
+ fixed (Vector256<UInt64>* pFld2 = &_fld2)
+ {
+ var result = Avx.TestZ(
+ Avx.LoadVector256((UInt64*)(pFld1)),
+ Avx.LoadVector256((UInt64*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx.TestZ(
+ Avx.LoadVector256((UInt64*)(&test._fld1)),
+ Avx.LoadVector256((UInt64*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt64> left, Vector256<UInt64> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt64> op1, Vector256<UInt64> op2, bool result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt64[] left, UInt64[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx)}.{nameof(Avx.TestZ)}<UInt64>(Vector256<UInt64>, Vector256<UInt64>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Xor.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Xor.Double.cs
index b98d285ebc..7c741a2538 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Xor.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Xor.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld1;
private Vector256<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var result = Avx.Xor(left, right);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var result = Avx.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.Xor(left, right);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var result = Avx.Xor(left, right);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var result = Avx.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> left, Vector256<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Xor.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Xor.Single.cs
index 3e1028209d..6415c48476 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx/Xor.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx/Xor.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld1;
private Vector256<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var result = Avx.Xor(left, right);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var result = Avx.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.Xor(left, right);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var result = Avx.Xor(left, right);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var result = Avx.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> left, Vector256<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Byte.cs
index e22a113af8..d4294d0ccf 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld1;
private Vector256<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
- var result = Avx2.Add(left, right);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Add(left, right);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Add(left, right);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int16.cs
index 479d451aea..4cf9c9e66d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.Add(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Add(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Add(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int32.cs
index 92f2e9a35e..2b9c37f2ed 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx2.Add(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Add(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Add(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int64.cs
index da5475ff78..dfd7ec030b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int64> _fld1;
private Vector256<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
- var result = Avx2.Add(left, right);
+ var op1 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx2.Add(left, right);
+ var op1 = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx2.Add(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int64> left, Vector256<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int64> op1, Vector256<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.SByte.cs
index 92a3f0ee6d..b078900135 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<SByte> _fld1;
private Vector256<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var result = Avx2.Add(left, right);
+ var op1 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Add(left, right);
+ var op1 = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Add(left, right);
+ var op1 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<SByte> op1, Vector256<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt16.cs
index 579887c700..1a5770dd0a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt16> _fld1;
private Vector256<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
- var result = Avx2.Add(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Add(left, right);
+ var op1 = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Add(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt16> op1, Vector256<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt32.cs
index 22ff7ab67b..56d1e1137f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt32> _fld1;
private Vector256<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
- var result = Avx2.Add(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Add(left, right);
+ var op1 = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Add(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt32> left, Vector256<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt32> op1, Vector256<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt64.cs
index 59e4d449b4..f7796b4d0c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Add.UInt64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt64> _fld1;
private Vector256<UInt64> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddUInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
- var result = Avx2.Add(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx2.Add(left, right);
+ var op1 = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx2.Add(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt64> left, Vector256<UInt64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt64> op1, Vector256<UInt64> op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Byte.cs
index f1b9fdc87a..50ef89c609 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld1;
private Vector256<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
- var result = Avx2.And(left, right);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.And(left, right);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.And(left, right);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Int16.cs
index 9a04193e84..6ceb4a7810 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.And(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.And(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.And(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Int32.cs
index feb16922fd..8345ad729d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx2.And(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.And(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.And(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Int64.cs
index 72ff8769c7..2bc07547de 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int64> _fld1;
private Vector256<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
- var result = Avx2.And(left, right);
+ var op1 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx2.And(left, right);
+ var op1 = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx2.And(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int64> left, Vector256<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int64> op1, Vector256<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.SByte.cs
index e9ea16177b..ef3dd702bc 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<SByte> _fld1;
private Vector256<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var result = Avx2.And(left, right);
+ var op1 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.And(left, right);
+ var op1 = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.And(left, right);
+ var op1 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<SByte> op1, Vector256<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.UInt16.cs
index 84ea0817e2..e93f96af07 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt16> _fld1;
private Vector256<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
- var result = Avx2.And(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.And(left, right);
+ var op1 = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.And(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt16> op1, Vector256<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.UInt32.cs
index 6a96c701c1..b647502d69 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt32> _fld1;
private Vector256<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
- var result = Avx2.And(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.And(left, right);
+ var op1 = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.And(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt32> left, Vector256<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt32> op1, Vector256<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.UInt64.cs
index 6cf1e7840a..4f13e0b506 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/And.UInt64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt64> _fld1;
private Vector256<UInt64> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndUInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
- var result = Avx2.And(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx2.And(left, right);
+ var op1 = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx2.And(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt64> left, Vector256<UInt64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt64> op1, Vector256<UInt64> op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Byte.cs
index 155d803328..924203a104 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld1;
private Vector256<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
- var result = Avx2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.AndNot(left, right);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.AndNot(left, right);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Int16.cs
index 35f3f08e4d..13ee2d45ee 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.AndNot(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.AndNot(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Int32.cs
index 7e4b7b28c4..64b899158e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.AndNot(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.AndNot(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Int64.cs
index e848fd8efb..91531d1a72 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int64> _fld1;
private Vector256<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
- var result = Avx2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx2.AndNot(left, right);
+ var op1 = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx2.AndNot(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int64> left, Vector256<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int64> op1, Vector256<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.SByte.cs
index ca9b65dbf8..57135af4a8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<SByte> _fld1;
private Vector256<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var result = Avx2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.AndNot(left, right);
+ var op1 = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.AndNot(left, right);
+ var op1 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<SByte> op1, Vector256<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.UInt16.cs
index 713ca9a2f2..99f7b11063 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt16> _fld1;
private Vector256<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
- var result = Avx2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.AndNot(left, right);
+ var op1 = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.AndNot(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt16> op1, Vector256<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.UInt32.cs
index 1a7102913d..d61966dc7d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt32> _fld1;
private Vector256<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
- var result = Avx2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.AndNot(left, right);
+ var op1 = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.AndNot(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt32> left, Vector256<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt32> op1, Vector256<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.UInt64.cs
index 1b4e0f75e8..2a1b0e9cca 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/AndNot.UInt64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt64> _fld1;
private Vector256<UInt64> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotUInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
- var result = Avx2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx2.AndNot(left, right);
+ var op1 = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx2.AndNot(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt64> left, Vector256<UInt64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt64> op1, Vector256<UInt64> op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Average.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Average.Byte.cs
index f5199c33ce..28eb94b3c5 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Average.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Average.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AverageByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld1;
private Vector256<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AverageByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
- var result = Avx2.Average(left, right);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Average(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Average(left, right);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Average(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Average(left, right);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Average(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Average.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Average.UInt16.cs
index 51ef47eecf..35361488f3 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Average.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Average.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AverageUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt16> _fld1;
private Vector256<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AverageUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
- var result = Avx2.Average(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Average(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Average(left, right);
+ var op1 = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Average(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Average(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Average(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt16> op1, Vector256<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj
index e23c63b662..b3e2a24905 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_r.csproj
@@ -276,10 +276,9 @@
<Compile Include="Xor.UInt64.cs" />
<Compile Include="Program.Avx2.cs" />
<Compile Include="..\Shared\Program.cs" />
+ <Compile Include="..\Shared\SimdScalarUnOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimdScalarUnOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_ro.csproj
index bfb260bd22..23a658d895 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Avx2_ro.csproj
@@ -276,10 +276,9 @@
<Compile Include="Xor.UInt64.cs" />
<Compile Include="Program.Avx2.cs" />
<Compile Include="..\Shared\Program.cs" />
+ <Compile Include="..\Shared\SimdScalarUnOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimdScalarUnOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Byte.cs
index 4b1fa7967c..33d11157e2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Byte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] inArray3, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Byte, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref testStruct._fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Byte>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (byte)(((i % 2) == 0) ? 128 : 1); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref _clsVar3), ref Unsafe.As<Byte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Byte>, byte>(ref testStruct._fld3), ref Unsafe.As<Byte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Byte>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableByte testClass)
+ {
+ fixed (Vector256<Byte>* pFld1 = &_fld1)
+ fixed (Vector256<Byte>* pFld2 = &_fld2)
+ fixed (Vector256<Byte>* pFld3 = &_fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Byte*)(pFld1)),
+ Avx.LoadVector256((Byte*)(pFld2)),
+ Avx.LoadVector256((Byte*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld2;
private Vector256<Byte> _fld3;
- private SimpleTernaryOpTest__DataTable<Byte, Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableByte()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (byte)(((i % 2) == 0) ? 128 : 1); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Byte, Byte, Byte, Byte>(_data1, _data2, _data3, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Byte>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Byte>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Byte>* pClsVar3 = &_clsVar3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Byte*)(pClsVar1)),
+ Avx.LoadVector256((Byte*)(pClsVar2)),
+ Avx.LoadVector256((Byte*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray3Ptr);
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray3Ptr);
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Byte*)(_dataTable.inArray3Ptr));
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Byte*)(_dataTable.inArray3Ptr));
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray3Ptr));
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray3Ptr));
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableByte();
+
+ fixed (Vector256<Byte>* pFld1 = &test._fld1)
+ fixed (Vector256<Byte>* pFld2 = &test._fld2)
+ fixed (Vector256<Byte>* pFld3 = &test._fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Byte*)(pFld1)),
+ Avx.LoadVector256((Byte*)(pFld2)),
+ Avx.LoadVector256((Byte*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Byte>* pFld1 = &_fld1)
+ fixed (Vector256<Byte>* pFld2 = &_fld2)
+ fixed (Vector256<Byte>* pFld3 = &_fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Byte*)(pFld1)),
+ Avx.LoadVector256((Byte*)(pFld2)),
+ Avx.LoadVector256((Byte*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Byte*)(&test._fld1)),
+ Avx.LoadVector256((Byte*)(&test._fld2)),
+ Avx.LoadVector256((Byte*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> firstOp, Vector256<Byte> secondOp, Vector256<Byte> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<Byte> op2, Vector256<Byte> op3, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] inArray3 = new Byte[Op3ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] inArray3 = new Byte[Op3ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BlendVariable)}<Byte>(Vector256<Byte>, Vector256<Byte>, Vector256<Byte>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int16.cs
index a099f4a89b..733f3f5ea8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] inArray3, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Int16, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref testStruct._fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Int16>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToInt16("0xFFFF", 16) : (short)0); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref _clsVar3), ref Unsafe.As<Int16, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int16>, byte>(ref testStruct._fld3), ref Unsafe.As<Int16, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Int16>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableInt16 testClass)
+ {
+ fixed (Vector256<Int16>* pFld1 = &_fld1)
+ fixed (Vector256<Int16>* pFld2 = &_fld2)
+ fixed (Vector256<Int16>* pFld3 = &_fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Int16*)(pFld1)),
+ Avx.LoadVector256((Int16*)(pFld2)),
+ Avx.LoadVector256((Int16*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld2;
private Vector256<Int16> _fld3;
- private SimpleTernaryOpTest__DataTable<Int16, Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableInt16()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToInt16("0xFFFF", 16) : (short)0); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Int16, Int16, Int16, Int16>(_data1, _data2, _data3, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Int16>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Int16>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Int16>* pClsVar3 = &_clsVar3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Int16*)(pClsVar1)),
+ Avx.LoadVector256((Int16*)(pClsVar2)),
+ Avx.LoadVector256((Int16*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray3Ptr);
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray3Ptr);
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Int16*)(_dataTable.inArray3Ptr));
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Int16*)(_dataTable.inArray3Ptr));
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray3Ptr));
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray3Ptr));
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableInt16();
+
+ fixed (Vector256<Int16>* pFld1 = &test._fld1)
+ fixed (Vector256<Int16>* pFld2 = &test._fld2)
+ fixed (Vector256<Int16>* pFld3 = &test._fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Int16*)(pFld1)),
+ Avx.LoadVector256((Int16*)(pFld2)),
+ Avx.LoadVector256((Int16*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Int16>* pFld1 = &_fld1)
+ fixed (Vector256<Int16>* pFld2 = &_fld2)
+ fixed (Vector256<Int16>* pFld3 = &_fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Int16*)(pFld1)),
+ Avx.LoadVector256((Int16*)(pFld2)),
+ Avx.LoadVector256((Int16*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Int16*)(&test._fld1)),
+ Avx.LoadVector256((Int16*)(&test._fld2)),
+ Avx.LoadVector256((Int16*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> firstOp, Vector256<Int16> secondOp, Vector256<Int16> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, Vector256<Int16> op3, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] inArray3 = new Int16[Op3ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] inArray3 = new Int16[Op3ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BlendVariable)}<Int16>(Vector256<Int16>, Vector256<Int16>, Vector256<Int16>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int32.cs
index 63dbc6a1d5..f2f51ec69d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] inArray3, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Int32, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref testStruct._fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Int32>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToInt32("0xFFFFFFFF", 16) : (int)0); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref _clsVar3), ref Unsafe.As<Int32, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int32>, byte>(ref testStruct._fld3), ref Unsafe.As<Int32, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Int32>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableInt32 testClass)
+ {
+ fixed (Vector256<Int32>* pFld1 = &_fld1)
+ fixed (Vector256<Int32>* pFld2 = &_fld2)
+ fixed (Vector256<Int32>* pFld3 = &_fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Int32*)(pFld1)),
+ Avx.LoadVector256((Int32*)(pFld2)),
+ Avx.LoadVector256((Int32*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld2;
private Vector256<Int32> _fld3;
- private SimpleTernaryOpTest__DataTable<Int32, Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableInt32()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToInt32("0xFFFFFFFF", 16) : (int)0); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Int32, Int32, Int32, Int32>(_data1, _data2, _data3, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Int32>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Int32>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Int32>* pClsVar3 = &_clsVar3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Int32*)(pClsVar1)),
+ Avx.LoadVector256((Int32*)(pClsVar2)),
+ Avx.LoadVector256((Int32*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray3Ptr);
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray3Ptr);
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Int32*)(_dataTable.inArray3Ptr));
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Int32*)(_dataTable.inArray3Ptr));
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray3Ptr));
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray3Ptr));
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableInt32();
+
+ fixed (Vector256<Int32>* pFld1 = &test._fld1)
+ fixed (Vector256<Int32>* pFld2 = &test._fld2)
+ fixed (Vector256<Int32>* pFld3 = &test._fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Int32*)(pFld1)),
+ Avx.LoadVector256((Int32*)(pFld2)),
+ Avx.LoadVector256((Int32*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Int32>* pFld1 = &_fld1)
+ fixed (Vector256<Int32>* pFld2 = &_fld2)
+ fixed (Vector256<Int32>* pFld3 = &_fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Int32*)(pFld1)),
+ Avx.LoadVector256((Int32*)(pFld2)),
+ Avx.LoadVector256((Int32*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Int32*)(&test._fld1)),
+ Avx.LoadVector256((Int32*)(&test._fld2)),
+ Avx.LoadVector256((Int32*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> firstOp, Vector256<Int32> secondOp, Vector256<Int32> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, Vector256<Int32> op3, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] inArray3 = new Int32[Op3ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] inArray3 = new Int32[Op3ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BlendVariable)}<Int32>(Vector256<Int32>, Vector256<Int32>, Vector256<Int32>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int64.cs
index d91e83e957..fab6bc1c9a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.Int64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] inArray3, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Int64, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int64> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref testStruct._fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Int64>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToInt64("0xFFFFFFFFFFFFFFFF", 16) : (long)0); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref _clsVar3), ref Unsafe.As<Int64, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Int64>, byte>(ref testStruct._fld3), ref Unsafe.As<Int64, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Int64>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableInt64 testClass)
+ {
+ fixed (Vector256<Int64>* pFld1 = &_fld1)
+ fixed (Vector256<Int64>* pFld2 = &_fld2)
+ fixed (Vector256<Int64>* pFld3 = &_fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Int64*)(pFld1)),
+ Avx.LoadVector256((Int64*)(pFld2)),
+ Avx.LoadVector256((Int64*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int64> _fld2;
private Vector256<Int64> _fld3;
- private SimpleTernaryOpTest__DataTable<Int64, Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableInt64()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToInt64("0xFFFFFFFFFFFFFFFF", 16) : (long)0); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Int64, Int64, Int64, Int64>(_data1, _data2, _data3, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Int64>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Int64>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Int64>* pClsVar3 = &_clsVar3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Int64*)(pClsVar1)),
+ Avx.LoadVector256((Int64*)(pClsVar2)),
+ Avx.LoadVector256((Int64*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray3Ptr);
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray3Ptr);
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Int64*)(_dataTable.inArray3Ptr));
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Int64*)(_dataTable.inArray3Ptr));
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray3Ptr));
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray3Ptr));
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableInt64();
+
+ fixed (Vector256<Int64>* pFld1 = &test._fld1)
+ fixed (Vector256<Int64>* pFld2 = &test._fld2)
+ fixed (Vector256<Int64>* pFld3 = &test._fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Int64*)(pFld1)),
+ Avx.LoadVector256((Int64*)(pFld2)),
+ Avx.LoadVector256((Int64*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Int64>* pFld1 = &_fld1)
+ fixed (Vector256<Int64>* pFld2 = &_fld2)
+ fixed (Vector256<Int64>* pFld3 = &_fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Int64*)(pFld1)),
+ Avx.LoadVector256((Int64*)(pFld2)),
+ Avx.LoadVector256((Int64*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((Int64*)(&test._fld1)),
+ Avx.LoadVector256((Int64*)(&test._fld2)),
+ Avx.LoadVector256((Int64*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int64> firstOp, Vector256<Int64> secondOp, Vector256<Int64> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int64> op1, Vector256<Int64> op2, Vector256<Int64> op3, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] inArray3 = new Int64[Op3ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] inArray3 = new Int64[Op3ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BlendVariable)}<Int64>(Vector256<Int64>, Vector256<Int64>, Vector256<Int64>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.SByte.cs
index 37c0ef5951..779d772c88 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.SByte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] inArray3, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<SByte, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<SByte> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref testStruct._fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<SByte>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (sbyte)(((i % 2) == 0) ? -128 : 1); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref _clsVar3), ref Unsafe.As<SByte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<SByte>, byte>(ref testStruct._fld3), ref Unsafe.As<SByte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<SByte>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableSByte testClass)
+ {
+ fixed (Vector256<SByte>* pFld1 = &_fld1)
+ fixed (Vector256<SByte>* pFld2 = &_fld2)
+ fixed (Vector256<SByte>* pFld3 = &_fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((SByte*)(pFld1)),
+ Avx.LoadVector256((SByte*)(pFld2)),
+ Avx.LoadVector256((SByte*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<SByte> _fld2;
private Vector256<SByte> _fld3;
- private SimpleTernaryOpTest__DataTable<SByte, SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableSByte()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (sbyte)(((i % 2) == 0) ? -128 : 1); }
- _dataTable = new SimpleTernaryOpTest__DataTable<SByte, SByte, SByte, SByte>(_data1, _data2, _data3, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<SByte>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<SByte>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<SByte>* pClsVar3 = &_clsVar3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((SByte*)(pClsVar1)),
+ Avx.LoadVector256((SByte*)(pClsVar2)),
+ Avx.LoadVector256((SByte*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray3Ptr);
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray3Ptr);
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((SByte*)(_dataTable.inArray3Ptr));
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((SByte*)(_dataTable.inArray3Ptr));
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray3Ptr));
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray3Ptr));
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableSByte();
+
+ fixed (Vector256<SByte>* pFld1 = &test._fld1)
+ fixed (Vector256<SByte>* pFld2 = &test._fld2)
+ fixed (Vector256<SByte>* pFld3 = &test._fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((SByte*)(pFld1)),
+ Avx.LoadVector256((SByte*)(pFld2)),
+ Avx.LoadVector256((SByte*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<SByte>* pFld1 = &_fld1)
+ fixed (Vector256<SByte>* pFld2 = &_fld2)
+ fixed (Vector256<SByte>* pFld3 = &_fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((SByte*)(pFld1)),
+ Avx.LoadVector256((SByte*)(pFld2)),
+ Avx.LoadVector256((SByte*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((SByte*)(&test._fld1)),
+ Avx.LoadVector256((SByte*)(&test._fld2)),
+ Avx.LoadVector256((SByte*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<SByte> firstOp, Vector256<SByte> secondOp, Vector256<SByte> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<SByte> op1, Vector256<SByte> op2, Vector256<SByte> op3, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] inArray3 = new SByte[Op3ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] inArray3 = new SByte[Op3ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BlendVariable)}<SByte>(Vector256<SByte>, Vector256<SByte>, Vector256<SByte>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.UInt16.cs
index 7f840f3af8..cc95c416dc 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.UInt16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] inArray3, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<UInt16, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt16> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToUInt16("0xFFFF", 16) : (ushort)0); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref _clsVar3), ref Unsafe.As<UInt16, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt16>, byte>(ref testStruct._fld3), ref Unsafe.As<UInt16, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableUInt16 testClass)
+ {
+ fixed (Vector256<UInt16>* pFld1 = &_fld1)
+ fixed (Vector256<UInt16>* pFld2 = &_fld2)
+ fixed (Vector256<UInt16>* pFld3 = &_fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((UInt16*)(pFld1)),
+ Avx.LoadVector256((UInt16*)(pFld2)),
+ Avx.LoadVector256((UInt16*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt16> _fld2;
private Vector256<UInt16> _fld3;
- private SimpleTernaryOpTest__DataTable<UInt16, UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableUInt16()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToUInt16("0xFFFF", 16) : (ushort)0); }
- _dataTable = new SimpleTernaryOpTest__DataTable<UInt16, UInt16, UInt16, UInt16>(_data1, _data2, _data3, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<UInt16>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<UInt16>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<UInt16>* pClsVar3 = &_clsVar3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((UInt16*)(pClsVar1)),
+ Avx.LoadVector256((UInt16*)(pClsVar2)),
+ Avx.LoadVector256((UInt16*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray3Ptr);
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray3Ptr);
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((UInt16*)(_dataTable.inArray3Ptr));
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((UInt16*)(_dataTable.inArray3Ptr));
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray3Ptr));
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray3Ptr));
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableUInt16();
+
+ fixed (Vector256<UInt16>* pFld1 = &test._fld1)
+ fixed (Vector256<UInt16>* pFld2 = &test._fld2)
+ fixed (Vector256<UInt16>* pFld3 = &test._fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((UInt16*)(pFld1)),
+ Avx.LoadVector256((UInt16*)(pFld2)),
+ Avx.LoadVector256((UInt16*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<UInt16>* pFld1 = &_fld1)
+ fixed (Vector256<UInt16>* pFld2 = &_fld2)
+ fixed (Vector256<UInt16>* pFld3 = &_fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((UInt16*)(pFld1)),
+ Avx.LoadVector256((UInt16*)(pFld2)),
+ Avx.LoadVector256((UInt16*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((UInt16*)(&test._fld1)),
+ Avx.LoadVector256((UInt16*)(&test._fld2)),
+ Avx.LoadVector256((UInt16*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt16> firstOp, Vector256<UInt16> secondOp, Vector256<UInt16> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt16> op1, Vector256<UInt16> op2, Vector256<UInt16> op3, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] inArray3 = new UInt16[Op3ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] inArray3 = new UInt16[Op3ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BlendVariable)}<UInt16>(Vector256<UInt16>, Vector256<UInt16>, Vector256<UInt16>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.UInt32.cs
index a192e9975d..4fe7030c23 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.UInt32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] inArray3, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<UInt32, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt32> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToUInt32("0xFFFFFFFF", 16) : (uint)0); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref _clsVar3), ref Unsafe.As<UInt32, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt32>, byte>(ref testStruct._fld3), ref Unsafe.As<UInt32, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableUInt32 testClass)
+ {
+ fixed (Vector256<UInt32>* pFld1 = &_fld1)
+ fixed (Vector256<UInt32>* pFld2 = &_fld2)
+ fixed (Vector256<UInt32>* pFld3 = &_fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((UInt32*)(pFld1)),
+ Avx.LoadVector256((UInt32*)(pFld2)),
+ Avx.LoadVector256((UInt32*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt32> _fld2;
private Vector256<UInt32> _fld3;
- private SimpleTernaryOpTest__DataTable<UInt32, UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableUInt32()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToUInt32("0xFFFFFFFF", 16) : (uint)0); }
- _dataTable = new SimpleTernaryOpTest__DataTable<UInt32, UInt32, UInt32, UInt32>(_data1, _data2, _data3, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<UInt32>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<UInt32>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<UInt32>* pClsVar3 = &_clsVar3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((UInt32*)(pClsVar1)),
+ Avx.LoadVector256((UInt32*)(pClsVar2)),
+ Avx.LoadVector256((UInt32*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray3Ptr);
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray3Ptr);
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((UInt32*)(_dataTable.inArray3Ptr));
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((UInt32*)(_dataTable.inArray3Ptr));
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray3Ptr));
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray3Ptr));
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableUInt32();
+
+ fixed (Vector256<UInt32>* pFld1 = &test._fld1)
+ fixed (Vector256<UInt32>* pFld2 = &test._fld2)
+ fixed (Vector256<UInt32>* pFld3 = &test._fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((UInt32*)(pFld1)),
+ Avx.LoadVector256((UInt32*)(pFld2)),
+ Avx.LoadVector256((UInt32*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<UInt32>* pFld1 = &_fld1)
+ fixed (Vector256<UInt32>* pFld2 = &_fld2)
+ fixed (Vector256<UInt32>* pFld3 = &_fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((UInt32*)(pFld1)),
+ Avx.LoadVector256((UInt32*)(pFld2)),
+ Avx.LoadVector256((UInt32*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((UInt32*)(&test._fld1)),
+ Avx.LoadVector256((UInt32*)(&test._fld2)),
+ Avx.LoadVector256((UInt32*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt32> firstOp, Vector256<UInt32> secondOp, Vector256<UInt32> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt32> op1, Vector256<UInt32> op2, Vector256<UInt32> op3, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] inArray3 = new UInt32[Op3ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] inArray3 = new UInt32[Op3ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BlendVariable)}<UInt32>(Vector256<UInt32>, Vector256<UInt32>, Vector256<UInt32>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.UInt64.cs
index b82b79c1e9..50563d2619 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BlendVariable.UInt64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] inArray3, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<UInt64, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt64> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToUInt64("0xFFFFFFFFFFFFFFFF", 16): (ulong)0); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref _clsVar3), ref Unsafe.As<UInt64, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<UInt64>, byte>(ref testStruct._fld3), ref Unsafe.As<UInt64, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableUInt64 testClass)
+ {
+ fixed (Vector256<UInt64>* pFld1 = &_fld1)
+ fixed (Vector256<UInt64>* pFld2 = &_fld2)
+ fixed (Vector256<UInt64>* pFld3 = &_fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((UInt64*)(pFld1)),
+ Avx.LoadVector256((UInt64*)(pFld2)),
+ Avx.LoadVector256((UInt64*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt64> _fld2;
private Vector256<UInt64> _fld3;
- private SimpleTernaryOpTest__DataTable<UInt64, UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableUInt64()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToUInt64("0xFFFFFFFFFFFFFFFF", 16): (ulong)0); }
- _dataTable = new SimpleTernaryOpTest__DataTable<UInt64, UInt64, UInt64, UInt64>(_data1, _data2, _data3, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<UInt64>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<UInt64>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<UInt64>* pClsVar3 = &_clsVar3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((UInt64*)(pClsVar1)),
+ Avx.LoadVector256((UInt64*)(pClsVar2)),
+ Avx.LoadVector256((UInt64*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray3Ptr);
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray3Ptr);
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((UInt64*)(_dataTable.inArray3Ptr));
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((UInt64*)(_dataTable.inArray3Ptr));
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray3Ptr));
- var result = Avx2.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray3Ptr));
+ var result = Avx2.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableUInt64();
+
+ fixed (Vector256<UInt64>* pFld1 = &test._fld1)
+ fixed (Vector256<UInt64>* pFld2 = &test._fld2)
+ fixed (Vector256<UInt64>* pFld3 = &test._fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((UInt64*)(pFld1)),
+ Avx.LoadVector256((UInt64*)(pFld2)),
+ Avx.LoadVector256((UInt64*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<UInt64>* pFld1 = &_fld1)
+ fixed (Vector256<UInt64>* pFld2 = &_fld2)
+ fixed (Vector256<UInt64>* pFld3 = &_fld3)
+ {
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((UInt64*)(pFld1)),
+ Avx.LoadVector256((UInt64*)(pFld2)),
+ Avx.LoadVector256((UInt64*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BlendVariable(
+ Avx.LoadVector256((UInt64*)(&test._fld1)),
+ Avx.LoadVector256((UInt64*)(&test._fld2)),
+ Avx.LoadVector256((UInt64*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt64> firstOp, Vector256<UInt64> secondOp, Vector256<UInt64> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt64> op1, Vector256<UInt64> op2, Vector256<UInt64> op3, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] inArray3 = new UInt64[Op3ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] inArray3 = new UInt64[Op3ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BlendVariable)}<UInt64>(Vector256<UInt64>, Vector256<UInt64>, Vector256<UInt64>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Byte.cs
index f4040e562e..fee179fffc 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Byte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector128Byte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Byte> _fld;
+ public Vector128<Byte> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector128Byte testClass)
{
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector128Byte testClass)
+ {
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Byte*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
- private static Byte[] _data = new Byte[Op1ElementCount];
+ private static Byte[] _data1 = new Byte[Op1ElementCount];
- private static Vector128<Byte> _clsVar;
+ private static Vector128<Byte> _clsVar1;
- private Vector128<Byte> _fld;
+ private Vector128<Byte> _fld1;
- private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector128Byte()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector128Byte()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+ _dataTable = new DataTable(_data1, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector128(
- Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Byte>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Byte>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Byte>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector128(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Byte>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Byte*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector128Byte();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector128Byte();
+
+ fixed (Vector128<Byte>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Byte*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Byte*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Byte*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, void* result, [CallerMemberName] string method = "")
{
- Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector128)}<Byte>(Vector128<Byte>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Double.cs
index 96eb1613a2..fbe534b823 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector128Double
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Double> _fld;
+ public Vector128<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector128Double testClass)
{
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector128Double testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector128<Double> _clsVar;
+ private static Vector128<Double> _clsVar1;
- private Vector128<Double> _fld;
+ private Vector128<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector128Double()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector128Double()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector128(
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector128(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector128Double();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector128Double();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector128)}<Double>(Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Int16.cs
index 6d7624b601..c558e1c03f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Int16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector128Int16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Int16> _fld;
+ public Vector128<Int16> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld), ref Unsafe.As<Int16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector128Int16 testClass)
{
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector128Int16 testClass)
+ {
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Int16*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int16>>() / sizeof(Int16);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Int16>>() / sizeof(Int16);
- private static Int16[] _data = new Int16[Op1ElementCount];
+ private static Int16[] _data1 = new Int16[Op1ElementCount];
- private static Vector128<Int16> _clsVar;
+ private static Vector128<Int16> _clsVar1;
- private Vector128<Int16> _fld;
+ private Vector128<Int16> _fld1;
- private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector128Int16()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector128Int16()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+ _dataTable = new DataTable(_data1, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector128(
- Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Int16>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Int16>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Int16>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int16>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector128(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int16>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Int16*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector128Int16();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector128Int16();
+
+ fixed (Vector128<Int16>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Int16*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Int16*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Int16*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, void* result, [CallerMemberName] string method = "")
{
- Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector128)}<Int16>(Vector128<Int16>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Int32.cs
index 4613c2e754..53575ccae6 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Int32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector128Int32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Int32> _fld;
+ public Vector128<Int32> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref testStruct._fld), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref testStruct._fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector128Int32 testClass)
{
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector128Int32 testClass)
+ {
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Int32*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int32>>() / sizeof(Int32);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Int32>>() / sizeof(Int32);
- private static Int32[] _data = new Int32[Op1ElementCount];
+ private static Int32[] _data1 = new Int32[Op1ElementCount];
- private static Vector128<Int32> _clsVar;
+ private static Vector128<Int32> _clsVar1;
- private Vector128<Int32> _fld;
+ private Vector128<Int32> _fld1;
- private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector128Int32()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector128Int32()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+ _dataTable = new DataTable(_data1, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector128(
- Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Int32>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Int32>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Int32>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int32>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector128(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int32>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Int32*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector128Int32();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector128Int32();
+
+ fixed (Vector128<Int32>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Int32*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Int32*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Int32*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, void* result, [CallerMemberName] string method = "")
{
- Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector128)}<Int32>(Vector128<Int32>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Int64.cs
index 0aa3890286..cdc360cf74 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Int64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector128Int64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Int64> _fld;
+ public Vector128<Int64> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld), ref Unsafe.As<Int64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector128Int64 testClass)
{
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector128Int64 testClass)
+ {
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Int64*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int64>>() / sizeof(Int64);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Int64>>() / sizeof(Int64);
- private static Int64[] _data = new Int64[Op1ElementCount];
+ private static Int64[] _data1 = new Int64[Op1ElementCount];
- private static Vector128<Int64> _clsVar;
+ private static Vector128<Int64> _clsVar1;
- private Vector128<Int64> _fld;
+ private Vector128<Int64> _fld1;
- private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector128Int64()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector128Int64()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+ _dataTable = new DataTable(_data1, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector128(
- Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Int64>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Int64>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Int64>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Int64>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector128(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int64>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Int64*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector128Int64();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector128Int64();
+
+ fixed (Vector128<Int64>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Int64*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Int64*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((Int64*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, void* result, [CallerMemberName] string method = "")
{
- Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector128)}<Int64>(Vector128<Int64>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.SByte.cs
index 7e8913e180..92df562c45 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.SByte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector128SByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<SByte> _fld;
+ public Vector128<SByte> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector128SByte testClass)
{
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector128SByte testClass)
+ {
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((SByte*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
- private static SByte[] _data = new SByte[Op1ElementCount];
+ private static SByte[] _data1 = new SByte[Op1ElementCount];
- private static Vector128<SByte> _clsVar;
+ private static Vector128<SByte> _clsVar1;
- private Vector128<SByte> _fld;
+ private Vector128<SByte> _fld1;
- private SimpleUnaryOpTest__DataTable<SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector128SByte()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector128SByte()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+ _dataTable = new DataTable(_data1, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector128(
- Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<SByte>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector128(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<SByte>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((SByte*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector128SByte();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector128SByte();
+
+ fixed (Vector128<SByte>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((SByte*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((SByte*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((SByte*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, void* result, [CallerMemberName] string method = "")
{
- SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector128)}<SByte>(Vector128<SByte>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Single.cs
index 7ec0e4aae4..c3e8701121 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector128Single
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Single> _fld;
+ public Vector128<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector128Single testClass)
{
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector128Single testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector128<Single> _clsVar;
+ private static Vector128<Single> _clsVar1;
- private Vector128<Single> _fld;
+ private Vector128<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector128Single()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector128Single()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector128(
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector128(
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector128(
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector128(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse.LoadVector128((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector128Single();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector128Single();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse.LoadVector128((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector128)}<Single>(Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.UInt16.cs
index adf87076c1..73bc9e7503 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.UInt16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector128UInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<UInt16> _fld;
+ public Vector128<UInt16> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref testStruct._fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector128UInt16 testClass)
{
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector128UInt16 testClass)
+ {
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((UInt16*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<UInt16>>() / sizeof(UInt16);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<UInt16>>() / sizeof(UInt16);
- private static UInt16[] _data = new UInt16[Op1ElementCount];
+ private static UInt16[] _data1 = new UInt16[Op1ElementCount];
- private static Vector128<UInt16> _clsVar;
+ private static Vector128<UInt16> _clsVar1;
- private Vector128<UInt16> _fld;
+ private Vector128<UInt16> _fld1;
- private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector128UInt16()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector128UInt16()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+ _dataTable = new DataTable(_data1, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector128(
- Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<UInt16>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<UInt16>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<UInt16>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector128(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt16>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((UInt16*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector128UInt16();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector128UInt16();
+
+ fixed (Vector128<UInt16>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((UInt16*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((UInt16*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((UInt16*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, void* result, [CallerMemberName] string method = "")
{
- UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector128)}<UInt16>(Vector128<UInt16>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.UInt32.cs
index b4c2bcd1a4..9b6760e69d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.UInt32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector128UInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<UInt32> _fld;
+ public Vector128<UInt32> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref testStruct._fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector128UInt32 testClass)
{
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector128UInt32 testClass)
+ {
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((UInt32*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<UInt32>>() / sizeof(UInt32);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<UInt32>>() / sizeof(UInt32);
- private static UInt32[] _data = new UInt32[Op1ElementCount];
+ private static UInt32[] _data1 = new UInt32[Op1ElementCount];
- private static Vector128<UInt32> _clsVar;
+ private static Vector128<UInt32> _clsVar1;
- private Vector128<UInt32> _fld;
+ private Vector128<UInt32> _fld1;
- private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector128UInt32()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector128UInt32()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+ _dataTable = new DataTable(_data1, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector128(
- Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<UInt32>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<UInt32>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<UInt32>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector128(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt32>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((UInt32*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector128UInt32();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector128UInt32();
+
+ fixed (Vector128<UInt32>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((UInt32*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((UInt32*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((UInt32*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, void* result, [CallerMemberName] string method = "")
{
- UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector128)}<UInt32>(Vector128<UInt32>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.UInt64.cs
index 8c66d7be35..323f63dfff 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector128.UInt64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector128UInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<UInt64> _fld;
+ public Vector128<UInt64> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector128UInt64 testClass)
{
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector128UInt64 testClass)
+ {
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((UInt64*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<UInt64>>() / sizeof(UInt64);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<UInt64>>() / sizeof(UInt64);
- private static UInt64[] _data = new UInt64[Op1ElementCount];
+ private static UInt64[] _data1 = new UInt64[Op1ElementCount];
- private static Vector128<UInt64> _clsVar;
+ private static Vector128<UInt64> _clsVar1;
- private Vector128<UInt64> _fld;
+ private Vector128<UInt64> _fld1;
- private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector128UInt64()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector128UInt64()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+ _dataTable = new DataTable(_data1, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector128(
- Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector128(
- Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<UInt64>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<UInt64>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector128), new Type[] { typeof(Vector128<UInt64>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt64>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector128(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt64>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((UInt64*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector128(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector128(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector128UInt64();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector128UInt64();
+
+ fixed (Vector128<UInt64>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((UInt64*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector128(_fld);
+ var result = Avx2.BroadcastScalarToVector128(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((UInt64*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector128(test._fld);
+ var result = Avx2.BroadcastScalarToVector128(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector128(
+ Sse2.LoadVector128((UInt64*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, void* result, [CallerMemberName] string method = "")
{
- UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector128)}<UInt64>(Vector128<UInt64>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Byte.cs
index 2c12caeb4b..573dfcb81a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Byte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector256Byte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Byte> _fld;
+ public Vector128<Byte> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector256Byte testClass)
{
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector256Byte testClass)
+ {
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Byte*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Byte>>() / sizeof(Byte);
- private static Byte[] _data = new Byte[Op1ElementCount];
+ private static Byte[] _data1 = new Byte[Op1ElementCount];
- private static Vector128<Byte> _clsVar;
+ private static Vector128<Byte> _clsVar1;
- private Vector128<Byte> _fld;
+ private Vector128<Byte> _fld1;
- private SimpleUnaryOpTest__DataTable<Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector256Byte()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector256Byte()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Byte, Byte>(_data, new Byte[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+ _dataTable = new DataTable(_data1, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector256(
- Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Byte>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Byte>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Byte>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Byte>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector256(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Byte>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Byte*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector256Byte();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector256Byte();
+
+ fixed (Vector128<Byte>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Byte*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Byte*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Byte*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, void* result, [CallerMemberName] string method = "")
{
- Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Byte[] firstOp, Byte[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector256)}<Byte>(Vector128<Byte>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Double.cs
index e45764903d..3d5a2b6133 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector256Double
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Double> _fld;
+ public Vector128<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector256Double testClass)
{
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector256Double testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector128<Double> _clsVar;
+ private static Vector128<Double> _clsVar1;
- private Vector128<Double> _fld;
+ private Vector128<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector256Double()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector256Double()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector256(
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector256(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector256Double();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector256Double();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector256)}<Double>(Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Int16.cs
index ca75f43c0e..f684077ce5 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Int16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector256Int16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Int16> _fld;
+ public Vector128<Int16> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld), ref Unsafe.As<Int16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector256Int16 testClass)
{
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector256Int16 testClass)
+ {
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Int16*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int16>>() / sizeof(Int16);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Int16>>() / sizeof(Int16);
- private static Int16[] _data = new Int16[Op1ElementCount];
+ private static Int16[] _data1 = new Int16[Op1ElementCount];
- private static Vector128<Int16> _clsVar;
+ private static Vector128<Int16> _clsVar1;
- private Vector128<Int16> _fld;
+ private Vector128<Int16> _fld1;
- private SimpleUnaryOpTest__DataTable<Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector256Int16()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector256Int16()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Int16, Int16>(_data, new Int16[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+ _dataTable = new DataTable(_data1, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector256(
- Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Int16>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Int16>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Int16>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int16>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector256(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int16>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Int16*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector256Int16();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector256Int16();
+
+ fixed (Vector128<Int16>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Int16*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Int16*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Int16*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, void* result, [CallerMemberName] string method = "")
{
- Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Int16[] firstOp, Int16[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector256)}<Int16>(Vector128<Int16>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Int32.cs
index 299780fa72..9cda642963 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Int32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector256Int32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Int32> _fld;
+ public Vector128<Int32> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref testStruct._fld), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref testStruct._fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector256Int32 testClass)
{
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector256Int32 testClass)
+ {
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Int32*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int32>>() / sizeof(Int32);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Int32>>() / sizeof(Int32);
- private static Int32[] _data = new Int32[Op1ElementCount];
+ private static Int32[] _data1 = new Int32[Op1ElementCount];
- private static Vector128<Int32> _clsVar;
+ private static Vector128<Int32> _clsVar1;
- private Vector128<Int32> _fld;
+ private Vector128<Int32> _fld1;
- private SimpleUnaryOpTest__DataTable<Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector256Int32()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector256Int32()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Int32, Int32>(_data, new Int32[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+ _dataTable = new DataTable(_data1, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector256(
- Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Int32>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Int32>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Int32>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int32>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector256(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int32>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Int32*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector256Int32();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector256Int32();
+
+ fixed (Vector128<Int32>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Int32*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Int32*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Int32*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, void* result, [CallerMemberName] string method = "")
{
- Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Int32[] firstOp, Int32[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector256)}<Int32>(Vector128<Int32>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Int64.cs
index 895cbf1a09..36c7505638 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Int64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector256Int64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Int64> _fld;
+ public Vector128<Int64> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld), ref Unsafe.As<Int64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector256Int64 testClass)
{
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector256Int64 testClass)
+ {
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Int64*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int64>>() / sizeof(Int64);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Int64>>() / sizeof(Int64);
- private static Int64[] _data = new Int64[Op1ElementCount];
+ private static Int64[] _data1 = new Int64[Op1ElementCount];
- private static Vector128<Int64> _clsVar;
+ private static Vector128<Int64> _clsVar1;
- private Vector128<Int64> _fld;
+ private Vector128<Int64> _fld1;
- private SimpleUnaryOpTest__DataTable<Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector256Int64()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector256Int64()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Int64, Int64>(_data, new Int64[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+ _dataTable = new DataTable(_data1, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector256(
- Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Int64>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Int64>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Int64>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Int64>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector256(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int64>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Int64*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector256Int64();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector256Int64();
+
+ fixed (Vector128<Int64>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Int64*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Int64*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((Int64*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, void* result, [CallerMemberName] string method = "")
{
- Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Int64[] firstOp, Int64[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector256)}<Int64>(Vector128<Int64>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.SByte.cs
index e95a975751..fd10693db7 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.SByte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector256SByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<SByte> _fld;
+ public Vector128<SByte> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector256SByte testClass)
{
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector256SByte testClass)
+ {
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((SByte*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<SByte>>() / sizeof(SByte);
- private static SByte[] _data = new SByte[Op1ElementCount];
+ private static SByte[] _data1 = new SByte[Op1ElementCount];
- private static Vector128<SByte> _clsVar;
+ private static Vector128<SByte> _clsVar1;
- private Vector128<SByte> _fld;
+ private Vector128<SByte> _fld1;
- private SimpleUnaryOpTest__DataTable<SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector256SByte()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector256SByte()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<SByte, SByte>(_data, new SByte[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+ _dataTable = new DataTable(_data1, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector256(
- Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<SByte>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector256(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<SByte>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((SByte*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector256SByte();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector256SByte();
+
+ fixed (Vector128<SByte>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((SByte*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((SByte*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((SByte*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, void* result, [CallerMemberName] string method = "")
{
- SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(SByte[] firstOp, SByte[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector256)}<SByte>(Vector128<SByte>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Single.cs
index 352208efd7..47d62d7fd8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector256Single
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Single> _fld;
+ public Vector128<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector256Single testClass)
{
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector256Single testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector128<Single> _clsVar;
+ private static Vector128<Single> _clsVar1;
- private Vector128<Single> _fld;
+ private Vector128<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector256Single()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector256Single()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector256(
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector256(
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector256(
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector256(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse.LoadVector128((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector256Single();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector256Single();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse.LoadVector128((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector256)}<Single>(Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.UInt16.cs
index 4bdd227cff..356f94ec72 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.UInt16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector256UInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<UInt16> _fld;
+ public Vector128<UInt16> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref testStruct._fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector256UInt16 testClass)
{
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector256UInt16 testClass)
+ {
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((UInt16*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<UInt16>>() / sizeof(UInt16);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<UInt16>>() / sizeof(UInt16);
- private static UInt16[] _data = new UInt16[Op1ElementCount];
+ private static UInt16[] _data1 = new UInt16[Op1ElementCount];
- private static Vector128<UInt16> _clsVar;
+ private static Vector128<UInt16> _clsVar1;
- private Vector128<UInt16> _fld;
+ private Vector128<UInt16> _fld1;
- private SimpleUnaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector256UInt16()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector256UInt16()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, UInt16>(_data, new UInt16[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+ _dataTable = new DataTable(_data1, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector256(
- Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<UInt16>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<UInt16>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<UInt16>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt16>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector256(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt16>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((UInt16*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector256UInt16();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector256UInt16();
+
+ fixed (Vector128<UInt16>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((UInt16*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((UInt16*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((UInt16*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, void* result, [CallerMemberName] string method = "")
{
- UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(UInt16[] firstOp, UInt16[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector256)}<UInt16>(Vector128<UInt16>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.UInt32.cs
index eb25d89b28..7b326c6538 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.UInt32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector256UInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<UInt32> _fld;
+ public Vector128<UInt32> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref testStruct._fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector256UInt32 testClass)
{
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector256UInt32 testClass)
+ {
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((UInt32*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<UInt32>>() / sizeof(UInt32);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<UInt32>>() / sizeof(UInt32);
- private static UInt32[] _data = new UInt32[Op1ElementCount];
+ private static UInt32[] _data1 = new UInt32[Op1ElementCount];
- private static Vector128<UInt32> _clsVar;
+ private static Vector128<UInt32> _clsVar1;
- private Vector128<UInt32> _fld;
+ private Vector128<UInt32> _fld1;
- private SimpleUnaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector256UInt32()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector256UInt32()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, UInt32>(_data, new UInt32[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+ _dataTable = new DataTable(_data1, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector256(
- Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<UInt32>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<UInt32>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<UInt32>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt32>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector256(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt32>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((UInt32*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector256UInt32();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector256UInt32();
+
+ fixed (Vector128<UInt32>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((UInt32*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((UInt32*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((UInt32*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, void* result, [CallerMemberName] string method = "")
{
- UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(UInt32[] firstOp, UInt32[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector256)}<UInt32>(Vector128<UInt32>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.UInt64.cs
index 338358a159..0edfaf2c5b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/BroadcastScalarToVector256.UInt64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__BroadcastScalarToVector256UInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<UInt64> _fld;
+ public Vector128<UInt64> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__BroadcastScalarToVector256UInt64 testClass)
{
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__BroadcastScalarToVector256UInt64 testClass)
+ {
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((UInt64*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<UInt64>>() / sizeof(UInt64);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector256<UInt64>>() / sizeof(UInt64);
- private static UInt64[] _data = new UInt64[Op1ElementCount];
+ private static UInt64[] _data1 = new UInt64[Op1ElementCount];
- private static Vector128<UInt64> _clsVar;
+ private static Vector128<UInt64> _clsVar1;
- private Vector128<UInt64> _fld;
+ private Vector128<UInt64> _fld1;
- private SimpleUnaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__BroadcastScalarToVector256UInt64()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
}
public SimpleUnaryOpTest__BroadcastScalarToVector256UInt64()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<UInt64, UInt64>(_data, new UInt64[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+ _dataTable = new DataTable(_data1, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Avx2.BroadcastScalarToVector256(
- Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Avx2.BroadcastScalarToVector256(
- Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<UInt64>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<UInt64>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Avx2).GetMethod(nameof(Avx2.BroadcastScalarToVector256), new Type[] { typeof(Vector128<UInt64>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector256<UInt64>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Avx2.BroadcastScalarToVector256(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt64>* pClsVar1 = &_clsVar1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((UInt64*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr);
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr));
- var result = Avx2.BroadcastScalarToVector256(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var result = Avx2.BroadcastScalarToVector256(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__BroadcastScalarToVector256UInt64();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__BroadcastScalarToVector256UInt64();
+
+ fixed (Vector128<UInt64>* pFld1 = &test._fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((UInt64*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Avx2.BroadcastScalarToVector256(_fld);
+ var result = Avx2.BroadcastScalarToVector256(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ {
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((UInt64*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Avx2.BroadcastScalarToVector256(test._fld);
+ var result = Avx2.BroadcastScalarToVector256(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Avx2.BroadcastScalarToVector256(
+ Sse2.LoadVector128((UInt64*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, void* result, [CallerMemberName] string method = "")
{
- UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(UInt64[] firstOp, UInt64[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Avx2)}.{nameof(Avx2.BroadcastScalarToVector256)}<UInt64>(Vector128<UInt64>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Byte.cs
index a347276305..b599def1bb 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld1;
private Vector256<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Int16.cs
index 9ba1108c48..4da2341700 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Int32.cs
index 1f469acba8..1562434de8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Int64.cs
index 5ca946cf50..559c1a0f90 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int64> _fld1;
private Vector256<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int64> left, Vector256<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int64> op1, Vector256<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.SByte.cs
index d0f186d1ce..3849137b4c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<SByte> _fld1;
private Vector256<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<SByte> op1, Vector256<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.UInt16.cs
index fa0882d25f..6c138b8db2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt16> _fld1;
private Vector256<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt16> op1, Vector256<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.UInt32.cs
index 8d15bda592..d4e716e564 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt32> _fld1;
private Vector256<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt32> left, Vector256<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt32> op1, Vector256<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.UInt64.cs
index 009965a105..c3f96c18ff 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareEqual.UInt64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt64> _fld1;
private Vector256<UInt64> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualUInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareEqual(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt64> left, Vector256<UInt64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt64> op1, Vector256<UInt64> op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.Int16.cs
index 743c6a0d35..49cf008efc 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareGreaterThanInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.CompareGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareGreaterThan(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareGreaterThan(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.Int32.cs
index 30dd80d13d..4ec03418ae 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareGreaterThanInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx2.CompareGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareGreaterThan(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareGreaterThan(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.Int64.cs
index 0eaf474c47..db455971ff 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int64> _fld1;
private Vector256<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareGreaterThanInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
- var result = Avx2.CompareGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareGreaterThan(left, right);
+ var op1 = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareGreaterThan(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int64> left, Vector256<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int64> op1, Vector256<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.SByte.cs
index f36556ca5f..62f187ddfe 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/CompareGreaterThan.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<SByte> _fld1;
private Vector256<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareGreaterThanSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var result = Avx2.CompareGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareGreaterThan(left, right);
+ var op1 = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.CompareGreaterThan(left, right);
+ var op1 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<SByte> op1, Vector256<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.Byte.cs
index 5573c2dd4b..2ba50303b5 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld1;
private Vector256<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
- var result = Avx2.Max(left, right);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Max(left, right);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Max(left, right);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.Int16.cs
index 06259c49a3..37c9283ccd 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.Max(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Max(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Max(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.Int32.cs
index b8d19d09e0..99b5a60937 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx2.Max(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Max(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Max(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.SByte.cs
index cba94a86cf..77d60cb66d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<SByte> _fld1;
private Vector256<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var result = Avx2.Max(left, right);
+ var op1 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Max(left, right);
+ var op1 = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Max(left, right);
+ var op1 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<SByte> op1, Vector256<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.UInt16.cs
index e48171c9f6..0e1691ea19 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt16> _fld1;
private Vector256<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
- var result = Avx2.Max(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Max(left, right);
+ var op1 = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Max(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt16> op1, Vector256<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.UInt32.cs
index e3f832efe6..94de5f6fcc 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Max.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt32> _fld1;
private Vector256<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
- var result = Avx2.Max(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Max(left, right);
+ var op1 = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Max(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt32> left, Vector256<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt32> op1, Vector256<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.Byte.cs
index 3a2ffd9836..6adcde9512 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld1;
private Vector256<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
- var result = Avx2.Min(left, right);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Min(left, right);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Min(left, right);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.Int16.cs
index f66c457ff0..2ec6886f6b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.Min(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Min(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Min(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.Int32.cs
index 1f0f215de7..337fa61b40 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx2.Min(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Min(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Min(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.SByte.cs
index 7a4021362d..bf084a5842 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<SByte> _fld1;
private Vector256<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var result = Avx2.Min(left, right);
+ var op1 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Min(left, right);
+ var op1 = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Min(left, right);
+ var op1 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<SByte> op1, Vector256<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.UInt16.cs
index 062ec8ed35..0ab8743517 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt16> _fld1;
private Vector256<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
- var result = Avx2.Min(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Min(left, right);
+ var op1 = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Min(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt16> op1, Vector256<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.UInt32.cs
index e98ac559f2..f32c40bb9b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Min.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt32> _fld1;
private Vector256<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
- var result = Avx2.Min(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Min(left, right);
+ var op1 = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Min(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt32> left, Vector256<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt32> op1, Vector256<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyAddAdjacent.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyAddAdjacent.Int16.cs
index d1773d6fad..aa6d0841b2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyAddAdjacent.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyAddAdjacent.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyAddAdjacentInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, SByte[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld1;
private Vector256<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Byte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyAddAdjacentInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Byte, SByte>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var result = Avx2.MultiplyAddAdjacent(left, right);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.MultiplyAddAdjacent(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyAddAdjacent(left, right);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyAddAdjacent(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyAddAdjacent(left, right);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyAddAdjacent(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> left, Vector256<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<SByte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyAddAdjacent.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyAddAdjacent.Int32.cs
index 4b7cca20d9..7f9ad2f1c4 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyAddAdjacent.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyAddAdjacent.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyAddAdjacentInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyAddAdjacentInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int16, Int16>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.MultiplyAddAdjacent(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.MultiplyAddAdjacent(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyAddAdjacent(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyAddAdjacent(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyAddAdjacent(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyAddAdjacent(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyHigh.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyHigh.Int16.cs
index b28ef21219..851d55a04e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyHigh.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyHigh.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyHighInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyHighInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.MultiplyHigh(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.MultiplyHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyHigh(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyHigh(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyHigh.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyHigh.UInt16.cs
index 9e57125452..c435dc690a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyHigh.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyHigh.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyHighUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt16> _fld1;
private Vector256<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyHighUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
- var result = Avx2.MultiplyHigh(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.MultiplyHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyHigh(left, right);
+ var op1 = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyHigh(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt16> op1, Vector256<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyHighRoundScale.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyHighRoundScale.Int16.cs
index 6ec92e4ce2..b3cf09def2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyHighRoundScale.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyHighRoundScale.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyHighRoundScaleInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyHighRoundScaleInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.MultiplyHighRoundScale(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.MultiplyHighRoundScale(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyHighRoundScale(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyHighRoundScale(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyHighRoundScale(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyHighRoundScale(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.Int16.cs
index 616939002b..a4d14d48dc 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyLowInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyLowInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.MultiplyLow(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyLow(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyLow(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.Int32.cs
index c3521952ba..28977af7b2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyLowInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyLowInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx2.MultiplyLow(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyLow(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyLow(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.UInt16.cs
index 1caa38df14..a639f61188 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyLowUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt16> _fld1;
private Vector256<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyLowUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
- var result = Avx2.MultiplyLow(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyLow(left, right);
+ var op1 = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyLow(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt16> op1, Vector256<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.UInt32.cs
index 806b9a4457..cbf9ca2550 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/MultiplyLow.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyLowUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt32> _fld1;
private Vector256<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyLowUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
- var result = Avx2.MultiplyLow(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyLow(left, right);
+ var op1 = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.MultiplyLow(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt32> left, Vector256<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt32> op1, Vector256<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Byte.cs
index c3a8875c34..926b7e2cea 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld1;
private Vector256<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
- var result = Avx2.Or(left, right);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Or(left, right);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Or(left, right);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Int16.cs
index 45e46a4c13..ebee6d935b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.Or(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Or(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Or(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Int32.cs
index 20386735ed..a360f9b8c9 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx2.Or(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Or(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Or(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Int64.cs
index 058745e575..ecca302cb2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int64> _fld1;
private Vector256<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
- var result = Avx2.Or(left, right);
+ var op1 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx2.Or(left, right);
+ var op1 = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx2.Or(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int64> left, Vector256<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int64> op1, Vector256<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.SByte.cs
index 82879ef754..a355137baa 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<SByte> _fld1;
private Vector256<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var result = Avx2.Or(left, right);
+ var op1 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Or(left, right);
+ var op1 = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Or(left, right);
+ var op1 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<SByte> op1, Vector256<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.UInt16.cs
index 789a1eaf46..47d03db7ea 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt16> _fld1;
private Vector256<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
- var result = Avx2.Or(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Or(left, right);
+ var op1 = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Or(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt16> op1, Vector256<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.UInt32.cs
index 4cde111ae0..76a6b9282c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt32> _fld1;
private Vector256<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
- var result = Avx2.Or(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Or(left, right);
+ var op1 = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Or(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt32> left, Vector256<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt32> op1, Vector256<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.UInt64.cs
index 17d6c389b8..323e99c5c1 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Or.UInt64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt64> _fld1;
private Vector256<UInt64> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrUInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
- var result = Avx2.Or(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx2.Or(left, right);
+ var op1 = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx2.Or(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt64> left, Vector256<UInt64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt64> op1, Vector256<UInt64> op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackSignedSaturate.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackSignedSaturate.Int16.cs
index ec4f69184c..fc2e97a8a9 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackSignedSaturate.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackSignedSaturate.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__PackSignedSaturateInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__PackSignedSaturateInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int32, Int32>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx2.PackSignedSaturate(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.PackSignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.PackSignedSaturate(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.PackSignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.PackSignedSaturate(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.PackSignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackSignedSaturate.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackSignedSaturate.SByte.cs
index ac303d9262..6d2760d954 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackSignedSaturate.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackSignedSaturate.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__PackSignedSaturateSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__PackSignedSaturateSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, Int16, Int16>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.PackSignedSaturate(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.PackSignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.PackSignedSaturate(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.PackSignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.PackSignedSaturate(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.PackSignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackUnsignedSaturate.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackUnsignedSaturate.Byte.cs
index 39ba009f12..2ff72da7de 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackUnsignedSaturate.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackUnsignedSaturate.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__PackUnsignedSaturateByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__PackUnsignedSaturateByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Int16, Int16>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.PackUnsignedSaturate(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.PackUnsignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.PackUnsignedSaturate(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.PackUnsignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.PackUnsignedSaturate(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.PackUnsignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackUnsignedSaturate.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackUnsignedSaturate.UInt16.cs
index 8edc61b44c..bde0f33ddc 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackUnsignedSaturate.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PackUnsignedSaturate.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__PackUnsignedSaturateUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__PackUnsignedSaturateUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, Int32, Int32>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx2.PackUnsignedSaturate(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.PackUnsignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.PackUnsignedSaturate(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.PackUnsignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.PackUnsignedSaturate(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.PackUnsignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PermuteVar8x32.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PermuteVar8x32.Int32.cs
index fb661c7a7e..16911931da 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PermuteVar8x32.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PermuteVar8x32.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__PermuteVar8x32Int32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__PermuteVar8x32Int32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx2.PermuteVar8x32(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.PermuteVar8x32(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.PermuteVar8x32(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.PermuteVar8x32(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.PermuteVar8x32(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.PermuteVar8x32(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PermuteVar8x32.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PermuteVar8x32.Single.cs
index 171a2390e9..12ed52ea7d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PermuteVar8x32.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PermuteVar8x32.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__PermuteVar8x32Single
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Int32[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__PermuteVar8x32Single()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Int32>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx2.PermuteVar8x32(left, right);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.PermuteVar8x32(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.PermuteVar8x32(left, right);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.PermuteVar8x32(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.PermuteVar8x32(left, right);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.PermuteVar8x32(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PermuteVar8x32.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PermuteVar8x32.UInt32.cs
index 96b4bd4454..d7804a05e3 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PermuteVar8x32.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/PermuteVar8x32.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__PermuteVar8x32UInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt32> _fld1;
private Vector256<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__PermuteVar8x32UInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
- var result = Avx2.PermuteVar8x32(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.PermuteVar8x32(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.PermuteVar8x32(left, right);
+ var op1 = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.PermuteVar8x32(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.PermuteVar8x32(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.PermuteVar8x32(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt32> left, Vector256<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt32> op1, Vector256<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmeticVariable.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmeticVariable.Int32.cs
index 1e809f76c7..ee5c8e009e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmeticVariable.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/ShiftRightArithmeticVariable.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__ShiftRightArithmeticVariableInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, UInt32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__ShiftRightArithmeticVariableInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (TestLibrary.Generator.GetUInt32()%32); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, UInt32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
- var result = Avx2.ShiftRightArithmeticVariable(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.ShiftRightArithmeticVariable(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.ShiftRightArithmeticVariable(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.ShiftRightArithmeticVariable(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.ShiftRightArithmeticVariable(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.ShiftRightArithmeticVariable(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Shuffle.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Shuffle.Byte.cs
index 847633bf55..1432dfcc06 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Shuffle.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Shuffle.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__ShuffleByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld1;
private Vector256<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__ShuffleByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
- var result = Avx2.Shuffle(left, right);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Shuffle(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Shuffle(left, right);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Shuffle(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Shuffle(left, right);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Shuffle(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Shuffle.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Shuffle.SByte.cs
index a48804ed42..d27de61053 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Shuffle.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Shuffle.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__ShuffleSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<SByte> _fld1;
private Vector256<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__ShuffleSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var result = Avx2.Shuffle(left, right);
+ var op1 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Shuffle(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Shuffle(left, right);
+ var op1 = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Shuffle(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Shuffle(left, right);
+ var op1 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Shuffle(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<SByte> op1, Vector256<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Sign.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Sign.Int16.cs
index 33aacd758c..15c48d4e21 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Sign.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Sign.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SignInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SignInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.Sign(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Sign(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Sign(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Sign.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Sign.Int32.cs
index df557bf3e0..9cfb56bddb 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Sign.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Sign.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SignInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SignInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx2.Sign(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Sign(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Sign(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Sign.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Sign.SByte.cs
index 245ab67210..8469a392bb 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Sign.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Sign.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SignSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<SByte> _fld1;
private Vector256<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SignSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var result = Avx2.Sign(left, right);
+ var op1 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Sign(left, right);
+ var op1 = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Sign(left, right);
+ var op1 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<SByte> op1, Vector256<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Byte.cs
index d289f55a64..1a0c4c6dfc 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld1;
private Vector256<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
- var result = Avx2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Subtract(left, right);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Subtract(left, right);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Int16.cs
index 8bb328e583..992aefd31d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Subtract(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Subtract(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Int32.cs
index 6614e583ba..12071faa61 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Subtract(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Subtract(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Int64.cs
index 610ded0ff6..331127c266 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int64> _fld1;
private Vector256<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
- var result = Avx2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx2.Subtract(left, right);
+ var op1 = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx2.Subtract(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int64> left, Vector256<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int64> op1, Vector256<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.SByte.cs
index 8f6b3a8baa..fed6aa9cca 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<SByte> _fld1;
private Vector256<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var result = Avx2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Subtract(left, right);
+ var op1 = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Subtract(left, right);
+ var op1 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<SByte> op1, Vector256<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.UInt16.cs
index fecb154b02..3b6a841f7f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt16> _fld1;
private Vector256<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
- var result = Avx2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Subtract(left, right);
+ var op1 = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Subtract(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt16> op1, Vector256<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.UInt32.cs
index c974629926..fca4768457 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt32> _fld1;
private Vector256<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
- var result = Avx2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Subtract(left, right);
+ var op1 = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Subtract(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt32> left, Vector256<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt32> op1, Vector256<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.UInt64.cs
index 35b0dd92e3..62bada053b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Subtract.UInt64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt64> _fld1;
private Vector256<UInt64> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractUInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
- var result = Avx2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx2.Subtract(left, right);
+ var op1 = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx2.Subtract(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt64> left, Vector256<UInt64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt64> op1, Vector256<UInt64> op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/SumAbsoluteDifferences.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/SumAbsoluteDifferences.UInt16.cs
index 13e2fa2e69..eba96da180 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/SumAbsoluteDifferences.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/SumAbsoluteDifferences.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SumAbsoluteDifferencesUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld1;
private Vector256<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SumAbsoluteDifferencesUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, Byte, Byte>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
- var result = Avx2.SumAbsoluteDifferences(left, right);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.SumAbsoluteDifferences(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.SumAbsoluteDifferences(left, right);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.SumAbsoluteDifferences(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.SumAbsoluteDifferences(left, right);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.SumAbsoluteDifferences(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Byte.cs
index 301f8c761d..8ad2d9af54 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Byte> _fld1;
private Vector256<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
- var result = Avx2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Byte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Xor(left, right);
+ var op1 = Avx.LoadVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Xor(left, right);
+ var op1 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Byte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Byte> left, Vector256<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Byte> op1, Vector256<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Int16.cs
index 17a6b75fd5..df1b33fed8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int16> _fld1;
private Vector256<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
- var result = Avx2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Xor(left, right);
+ var op1 = Avx.LoadVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Xor(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int16> left, Vector256<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int16> op1, Vector256<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Int32.cs
index b1937291d7..c9b6c4e1af 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int32> _fld1;
private Vector256<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Xor(left, right);
+ var op1 = Avx.LoadVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Xor(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int32> left, Vector256<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int32> op1, Vector256<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Int64.cs
index 3ad0d1c515..cee130fe14 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Int64> _fld1;
private Vector256<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
- var result = Avx2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx2.Xor(left, right);
+ var op1 = Avx.LoadVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx2.Xor(left, right);
+ var op1 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Int64> left, Vector256<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Int64> op1, Vector256<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.SByte.cs
index 06cc982b1e..5b931bc4df 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<SByte> _fld1;
private Vector256<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
- var result = Avx2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<SByte>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Xor(left, right);
+ var op1 = Avx.LoadVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
- var result = Avx2.Xor(left, right);
+ var op1 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((SByte*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<SByte> left, Vector256<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<SByte> op1, Vector256<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.UInt16.cs
index e87af71e6f..cd9304fab8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt16> _fld1;
private Vector256<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
- var result = Avx2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Xor(left, right);
+ var op1 = Avx.LoadVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
- var result = Avx2.Xor(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt16> left, Vector256<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt16> op1, Vector256<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.UInt32.cs
index e41df82bd9..839b37af92 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt32> _fld1;
private Vector256<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
- var result = Avx2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Xor(left, right);
+ var op1 = Avx.LoadVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.Xor(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt32> left, Vector256<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt32> op1, Vector256<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.UInt64.cs
index 43a3683e75..af421b9b87 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2/Xor.UInt64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<UInt64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<UInt64> _fld1;
private Vector256<UInt64> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorUInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
- var result = Avx2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx2.Xor(left, right);
+ var op1 = Avx.LoadVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
- var result = Avx2.Xor(left, right);
+ var op1 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Avx2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<UInt64> left, Vector256<UInt64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<UInt64> op1, Vector256<UInt64> op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx2_Vector128/ShiftRightArithmeticVariable.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx2_Vector128/ShiftRightArithmeticVariable.Int32.cs
index daa905ad4f..b2abd55caa 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx2_Vector128/ShiftRightArithmeticVariable.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx2_Vector128/ShiftRightArithmeticVariable.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__ShiftRightArithmeticVariableInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, UInt32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__ShiftRightArithmeticVariableInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (TestLibrary.Generator.GetUInt32() % 32); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, UInt32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Avx2.ShiftRightArithmeticVariable(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Avx2.ShiftRightArithmeticVariable(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.ShiftRightArithmeticVariable(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.ShiftRightArithmeticVariable(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Avx2.ShiftRightArithmeticVariable(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Avx2.ShiftRightArithmeticVariable(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx_Vector128/PermuteVar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx_Vector128/PermuteVar.Double.cs
index d5ef0751c5..0fb39249ca 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx_Vector128/PermuteVar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx_Vector128/PermuteVar.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__PermuteVarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Int64[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__PermuteVarDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = (long)1; }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Int64>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var result = Avx.PermuteVar(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Avx.PermuteVar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx.PermuteVar(left, right);
+ var op1 = Avx.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx.PermuteVar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Avx.PermuteVar(left, right);
+ var op1 = Avx.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Avx.PermuteVar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Avx_Vector128/PermuteVar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Avx_Vector128/PermuteVar.Single.cs
index 1bf603d0f7..b1ad49d992 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Avx_Vector128/PermuteVar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Avx_Vector128/PermuteVar.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__PermuteVarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Int32[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__PermuteVarSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = 1; }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Int32>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Avx.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Avx.PermuteVar(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Avx.PermuteVar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Avx.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx.PermuteVar(left, right);
+ var op1 = Avx.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx.PermuteVar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Avx.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Avx.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Avx.PermuteVar(left, right);
+ var op1 = Avx.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Avx.PermuteVar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/Fma_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/Fma_r.csproj
index bffaeab915..3bc2a1de0a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/Fma_r.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/Fma_r.csproj
@@ -48,9 +48,7 @@
<Compile Include="MultiplySubtractScalar.Single.cs" />
<Compile Include="MultiplySubtractScalar.Double.cs" />
<Compile Include="Program.Fma_Vector128.cs" />
- <Compile Include="..\Shared\AlternatingTernOpTest_DataTable.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/Fma_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/Fma_ro.csproj
index e155e135c7..729a234a58 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/Fma_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/Fma_ro.csproj
@@ -48,9 +48,7 @@
<Compile Include="MultiplySubtractScalar.Single.cs" />
<Compile Include="MultiplySubtractScalar.Double.cs" />
<Compile Include="Program.Fma_Vector128.cs" />
- <Compile Include="..\Shared\AlternatingTernOpTest_DataTable.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAdd.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAdd.Double.cs
index 3f5cb2a5f1..5a69190268 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAdd.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAdd.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplyAddDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplyAddDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAdd(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld2;
private Vector128<Double> _fld3;
- private SimpleTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplyAddDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplyAdd(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2)),
+ Sse2.LoadVector128((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplyAdd(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplyAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAdd(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAdd(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplyAddDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ fixed (Vector128<Double>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplyAdd(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAdd(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplyAdd(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2)),
+ Sse2.LoadVector128((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, Vector128<Double> secondOp, Vector128<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, Vector128<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplyAdd)}<Double>(Vector128<Double>, Vector128<Double>, Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAdd.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAdd.Single.cs
index 2d17488d14..7199d6aec3 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAdd.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAdd.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplyAddSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplyAddSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAdd(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld2;
private Vector128<Single> _fld3;
- private SimpleTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplyAddSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplyAdd(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2)),
+ Sse.LoadVector128((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplyAdd(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplyAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAdd(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAdd(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplyAddSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ fixed (Vector128<Single>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplyAdd(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAdd(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplyAdd(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2)),
+ Sse.LoadVector128((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, Vector128<Single> secondOp, Vector128<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, Vector128<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplyAdd)}<Single>(Vector128<Single>, Vector128<Single>, Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegated.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegated.Double.cs
index d26e791133..28016115dd 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegated.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegated.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplyAddNegatedDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplyAddNegatedDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddNegated(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld2;
private Vector128<Double> _fld3;
- private SimpleTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplyAddNegatedDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplyAddNegated(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2)),
+ Sse2.LoadVector128((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplyAddNegated(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplyAddNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddNegated(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddNegated(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplyAddNegatedDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ fixed (Vector128<Double>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplyAddNegated(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddNegated(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplyAddNegated(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2)),
+ Sse2.LoadVector128((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, Vector128<Double> secondOp, Vector128<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, Vector128<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplyAddNegated)}<Double>(Vector128<Double>, Vector128<Double>, Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegated.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegated.Single.cs
index f0a7a7664f..0578c03d87 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegated.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegated.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplyAddNegatedSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplyAddNegatedSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddNegated(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld2;
private Vector128<Single> _fld3;
- private SimpleTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplyAddNegatedSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplyAddNegated(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2)),
+ Sse.LoadVector128((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplyAddNegated(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplyAddNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddNegated(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddNegated(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplyAddNegatedSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ fixed (Vector128<Single>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplyAddNegated(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddNegated(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplyAddNegated(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2)),
+ Sse.LoadVector128((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, Vector128<Single> secondOp, Vector128<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, Vector128<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplyAddNegated)}<Single>(Vector128<Single>, Vector128<Single>, Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegatedScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegatedScalar.Double.cs
index 455f1e7814..70c1f48ee8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegatedScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegatedScalar.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplyAddNegatedScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplyAddNegatedScalarDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddNegatedScalar(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld2;
private Vector128<Double> _fld3;
- private SimpleTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplyAddNegatedScalarDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplyAddNegatedScalar(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2)),
+ Sse2.LoadVector128((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplyAddNegatedScalar(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplyAddNegatedScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddNegatedScalar(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddNegatedScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddNegatedScalar(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddNegatedScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplyAddNegatedScalarDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ fixed (Vector128<Double>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplyAddNegatedScalar(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddNegatedScalar(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplyAddNegatedScalar(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2)),
+ Sse2.LoadVector128((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, Vector128<Double> secondOp, Vector128<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, Vector128<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplyAddNegatedScalar)}<Double>(Vector128<Double>, Vector128<Double>, Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegatedScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegatedScalar.Single.cs
index 19515c0d02..090b00d7c3 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegatedScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddNegatedScalar.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplyAddNegatedScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplyAddNegatedScalarSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddNegatedScalar(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld2;
private Vector128<Single> _fld3;
- private SimpleTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplyAddNegatedScalarSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplyAddNegatedScalar(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2)),
+ Sse.LoadVector128((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplyAddNegatedScalar(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplyAddNegatedScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddNegatedScalar(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddNegatedScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddNegatedScalar(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddNegatedScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplyAddNegatedScalarSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ fixed (Vector128<Single>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplyAddNegatedScalar(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddNegatedScalar(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplyAddNegatedScalar(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2)),
+ Sse.LoadVector128((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, Vector128<Single> secondOp, Vector128<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, Vector128<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplyAddNegatedScalar)}<Single>(Vector128<Single>, Vector128<Single>, Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddScalar.Double.cs
index cf99925476..2afb67d969 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddScalar.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplyAddScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplyAddScalarDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddScalar(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld2;
private Vector128<Double> _fld3;
- private SimpleTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplyAddScalarDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplyAddScalar(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2)),
+ Sse2.LoadVector128((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplyAddScalar(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplyAddScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddScalar(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddScalar(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplyAddScalarDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ fixed (Vector128<Double>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplyAddScalar(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddScalar(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplyAddScalar(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2)),
+ Sse2.LoadVector128((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, Vector128<Double> secondOp, Vector128<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, Vector128<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplyAddScalar)}<Double>(Vector128<Double>, Vector128<Double>, Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddScalar.Single.cs
index aa456e9be3..03361c903e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddScalar.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplyAddScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplyAddScalarSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddScalar(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld2;
private Vector128<Single> _fld3;
- private SimpleTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplyAddScalarSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplyAddScalar(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2)),
+ Sse.LoadVector128((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplyAddScalar(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplyAddScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddScalar(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddScalar(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplyAddScalarSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ fixed (Vector128<Single>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplyAddScalar(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddScalar(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplyAddScalar(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2)),
+ Sse.LoadVector128((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, Vector128<Single> secondOp, Vector128<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, Vector128<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplyAddScalar)}<Single>(Vector128<Single>, Vector128<Single>, Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddSubtract.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddSubtract.Double.cs
index 3335571198..07b1e02387 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddSubtract.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddSubtract.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class AlternatingTernaryOpTest__MultiplyAddSubtractDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(AlternatingTernaryOpTest__MultiplyAddSubtractDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddSubtract(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld2;
private Vector128<Double> _fld3;
- private AlternatingTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static AlternatingTernaryOpTest__MultiplyAddSubtractDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new AlternatingTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplyAddSubtract(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2)),
+ Sse2.LoadVector128((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplyAddSubtract(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplyAddSubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddSubtract(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddSubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddSubtract(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddSubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new AlternatingTernaryOpTest__MultiplyAddSubtractDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ fixed (Vector128<Double>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplyAddSubtract(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddSubtract(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplyAddSubtract(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2)),
+ Sse2.LoadVector128((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, Vector128<Double> secondOp, Vector128<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, Vector128<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -425,10 +615,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplyAddSubtract)}<Double>(Vector128<Double>, Vector128<Double>, Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddSubtract.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddSubtract.Single.cs
index 43f7fe879f..dc77464cd2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddSubtract.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplyAddSubtract.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class AlternatingTernaryOpTest__MultiplyAddSubtractSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(AlternatingTernaryOpTest__MultiplyAddSubtractSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddSubtract(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld2;
private Vector128<Single> _fld3;
- private AlternatingTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static AlternatingTernaryOpTest__MultiplyAddSubtractSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new AlternatingTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplyAddSubtract(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2)),
+ Sse.LoadVector128((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplyAddSubtract(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplyAddSubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddSubtract(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddSubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddSubtract(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddSubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new AlternatingTernaryOpTest__MultiplyAddSubtractSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ fixed (Vector128<Single>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplyAddSubtract(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddSubtract(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplyAddSubtract(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2)),
+ Sse.LoadVector128((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, Vector128<Single> secondOp, Vector128<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, Vector128<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -425,10 +615,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplyAddSubtract)}<Single>(Vector128<Single>, Vector128<Single>, Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtract.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtract.Double.cs
index b406d3d226..873384dbe7 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtract.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtract.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplySubtractDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplySubtractDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtract(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld2;
private Vector128<Double> _fld3;
- private SimpleTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplySubtractDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplySubtract(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2)),
+ Sse2.LoadVector128((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplySubtract(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplySubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtract(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtract(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplySubtractDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ fixed (Vector128<Double>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplySubtract(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtract(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplySubtract(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2)),
+ Sse2.LoadVector128((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, Vector128<Double> secondOp, Vector128<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, Vector128<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplySubtract)}<Double>(Vector128<Double>, Vector128<Double>, Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtract.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtract.Single.cs
index a03084c3ac..4a58b4398c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtract.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtract.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplySubtractSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplySubtractSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtract(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld2;
private Vector128<Single> _fld3;
- private SimpleTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplySubtractSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplySubtract(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2)),
+ Sse.LoadVector128((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplySubtract(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplySubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtract(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtract(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplySubtractSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ fixed (Vector128<Single>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplySubtract(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtract(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplySubtract(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2)),
+ Sse.LoadVector128((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, Vector128<Single> secondOp, Vector128<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, Vector128<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplySubtract)}<Single>(Vector128<Single>, Vector128<Single>, Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractAdd.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractAdd.Double.cs
index 10fe6ae9dd..080d6e13ba 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractAdd.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractAdd.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class AlternatingTernaryOpTest__MultiplySubtractAddDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(AlternatingTernaryOpTest__MultiplySubtractAddDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractAdd(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld2;
private Vector128<Double> _fld3;
- private AlternatingTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static AlternatingTernaryOpTest__MultiplySubtractAddDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new AlternatingTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplySubtractAdd(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2)),
+ Sse2.LoadVector128((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplySubtractAdd(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplySubtractAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractAdd(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractAdd(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new AlternatingTernaryOpTest__MultiplySubtractAddDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ fixed (Vector128<Double>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplySubtractAdd(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractAdd(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplySubtractAdd(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2)),
+ Sse2.LoadVector128((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, Vector128<Double> secondOp, Vector128<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, Vector128<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -425,10 +615,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplySubtractAdd)}<Double>(Vector128<Double>, Vector128<Double>, Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractAdd.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractAdd.Single.cs
index 2c0e729279..ac6d6641c1 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractAdd.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractAdd.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class AlternatingTernaryOpTest__MultiplySubtractAddSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(AlternatingTernaryOpTest__MultiplySubtractAddSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractAdd(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld2;
private Vector128<Single> _fld3;
- private AlternatingTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static AlternatingTernaryOpTest__MultiplySubtractAddSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new AlternatingTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplySubtractAdd(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2)),
+ Sse.LoadVector128((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplySubtractAdd(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplySubtractAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractAdd(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractAdd(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new AlternatingTernaryOpTest__MultiplySubtractAddSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ fixed (Vector128<Single>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplySubtractAdd(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractAdd(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplySubtractAdd(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2)),
+ Sse.LoadVector128((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, Vector128<Single> secondOp, Vector128<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, Vector128<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -425,10 +615,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplySubtractAdd)}<Single>(Vector128<Single>, Vector128<Single>, Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegated.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegated.Double.cs
index f0f9b0721e..2e6a78e7b4 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegated.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegated.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplySubtractNegatedDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplySubtractNegatedDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractNegated(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld2;
private Vector128<Double> _fld3;
- private SimpleTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplySubtractNegatedDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplySubtractNegated(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2)),
+ Sse2.LoadVector128((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplySubtractNegated(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplySubtractNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractNegated(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractNegated(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplySubtractNegatedDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ fixed (Vector128<Double>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplySubtractNegated(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractNegated(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplySubtractNegated(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2)),
+ Sse2.LoadVector128((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, Vector128<Double> secondOp, Vector128<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, Vector128<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplySubtractNegated)}<Double>(Vector128<Double>, Vector128<Double>, Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegated.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegated.Single.cs
index 736751d754..bc251020ee 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegated.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegated.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplySubtractNegatedSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplySubtractNegatedSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractNegated(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld2;
private Vector128<Single> _fld3;
- private SimpleTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplySubtractNegatedSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplySubtractNegated(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2)),
+ Sse.LoadVector128((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplySubtractNegated(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplySubtractNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractNegated(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractNegated(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplySubtractNegatedSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ fixed (Vector128<Single>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplySubtractNegated(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractNegated(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplySubtractNegated(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2)),
+ Sse.LoadVector128((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, Vector128<Single> secondOp, Vector128<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, Vector128<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplySubtractNegated)}<Single>(Vector128<Single>, Vector128<Single>, Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegatedScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegatedScalar.Double.cs
index 2c7026e725..177fae17bf 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegatedScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegatedScalar.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplySubtractNegatedScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplySubtractNegatedScalarDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractNegatedScalar(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld2;
private Vector128<Double> _fld3;
- private SimpleTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplySubtractNegatedScalarDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplySubtractNegatedScalar(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2)),
+ Sse2.LoadVector128((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplySubtractNegatedScalar(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplySubtractNegatedScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractNegatedScalar(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractNegatedScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractNegatedScalar(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractNegatedScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplySubtractNegatedScalarDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ fixed (Vector128<Double>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplySubtractNegatedScalar(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractNegatedScalar(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplySubtractNegatedScalar(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2)),
+ Sse2.LoadVector128((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, Vector128<Double> secondOp, Vector128<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, Vector128<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplySubtractNegatedScalar)}<Double>(Vector128<Double>, Vector128<Double>, Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegatedScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegatedScalar.Single.cs
index 6a22de7255..89eeed9692 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegatedScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractNegatedScalar.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplySubtractNegatedScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplySubtractNegatedScalarSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractNegatedScalar(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld2;
private Vector128<Single> _fld3;
- private SimpleTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplySubtractNegatedScalarSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplySubtractNegatedScalar(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2)),
+ Sse.LoadVector128((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplySubtractNegatedScalar(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplySubtractNegatedScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractNegatedScalar(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractNegatedScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractNegatedScalar(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractNegatedScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplySubtractNegatedScalarSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ fixed (Vector128<Single>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplySubtractNegatedScalar(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractNegatedScalar(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplySubtractNegatedScalar(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2)),
+ Sse.LoadVector128((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, Vector128<Single> secondOp, Vector128<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, Vector128<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplySubtractNegatedScalar)}<Single>(Vector128<Single>, Vector128<Single>, Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractScalar.Double.cs
index 68f1e77b6d..d76b860333 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractScalar.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplySubtractScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplySubtractScalarDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractScalar(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld2;
private Vector128<Double> _fld3;
- private SimpleTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplySubtractScalarDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplySubtractScalar(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2)),
+ Sse2.LoadVector128((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplySubtractScalar(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplySubtractScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractScalar(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractScalar(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplySubtractScalarDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ fixed (Vector128<Double>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplySubtractScalar(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractScalar(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplySubtractScalar(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2)),
+ Sse2.LoadVector128((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, Vector128<Double> secondOp, Vector128<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, Vector128<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplySubtractScalar)}<Double>(Vector128<Double>, Vector128<Double>, Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractScalar.Single.cs
index 85e93468d9..da82530264 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector128/MultiplySubtractScalar.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplySubtractScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplySubtractScalarSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractScalar(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld2;
private Vector128<Single> _fld3;
- private SimpleTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplySubtractScalarSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplySubtractScalar(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2)),
+ Sse.LoadVector128((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplySubtractScalar(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplySubtractScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractScalar(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractScalar(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractScalar(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplySubtractScalarSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ fixed (Vector128<Single>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplySubtractScalar(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractScalar(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplySubtractScalar(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2)),
+ Sse.LoadVector128((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, Vector128<Single> secondOp, Vector128<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, Vector128<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplySubtractScalar)}<Single>(Vector128<Single>, Vector128<Single>, Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/Fma_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/Fma_r.csproj
index c791912247..684e3152c6 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/Fma_r.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/Fma_r.csproj
@@ -40,9 +40,7 @@
<Compile Include="MultiplySubtractNegated.Double.cs" />
<Compile Include="MultiplySubtractNegated.Single.cs" />
<Compile Include="Program.Fma_Vector256.cs" />
- <Compile Include="..\Shared\AlternatingTernOpTest_DataTable.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/Fma_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/Fma_ro.csproj
index 495ade6c68..11ac4626a7 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/Fma_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/Fma_ro.csproj
@@ -40,9 +40,7 @@
<Compile Include="MultiplySubtractNegated.Double.cs" />
<Compile Include="MultiplySubtractNegated.Single.cs" />
<Compile Include="Program.Fma_Vector256.cs" />
- <Compile Include="..\Shared\AlternatingTernOpTest_DataTable.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAdd.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAdd.Double.cs
index dbad50d75e..1167527129 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAdd.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAdd.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplyAddDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplyAddDouble testClass)
+ {
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ fixed (Vector256<Double>* pFld2 = &_fld2)
+ fixed (Vector256<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAdd(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld2;
private Vector256<Double> _fld3;
- private SimpleTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplyAddDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplyAdd(
+ Avx.LoadVector256((Double*)(pClsVar1)),
+ Avx.LoadVector256((Double*)(pClsVar2)),
+ Avx.LoadVector256((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplyAdd(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplyAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAdd(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAdd(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplyAddDouble();
+
+ fixed (Vector256<Double>* pFld1 = &test._fld1)
+ fixed (Vector256<Double>* pFld2 = &test._fld2)
+ fixed (Vector256<Double>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplyAdd(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ fixed (Vector256<Double>* pFld2 = &_fld2)
+ fixed (Vector256<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAdd(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplyAdd(
+ Avx.LoadVector256((Double*)(&test._fld1)),
+ Avx.LoadVector256((Double*)(&test._fld2)),
+ Avx.LoadVector256((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> firstOp, Vector256<Double> secondOp, Vector256<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, Vector256<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplyAdd)}<Double>(Vector256<Double>, Vector256<Double>, Vector256<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAdd.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAdd.Single.cs
index f555c58f1b..6acf33ec9d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAdd.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAdd.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplyAddSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplyAddSingle testClass)
+ {
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ fixed (Vector256<Single>* pFld2 = &_fld2)
+ fixed (Vector256<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAdd(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld2;
private Vector256<Single> _fld3;
- private SimpleTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplyAddSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplyAdd(
+ Avx.LoadVector256((Single*)(pClsVar1)),
+ Avx.LoadVector256((Single*)(pClsVar2)),
+ Avx.LoadVector256((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplyAdd(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplyAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAdd(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAdd(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplyAddSingle();
+
+ fixed (Vector256<Single>* pFld1 = &test._fld1)
+ fixed (Vector256<Single>* pFld2 = &test._fld2)
+ fixed (Vector256<Single>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplyAdd(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ fixed (Vector256<Single>* pFld2 = &_fld2)
+ fixed (Vector256<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAdd(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplyAdd(
+ Avx.LoadVector256((Single*)(&test._fld1)),
+ Avx.LoadVector256((Single*)(&test._fld2)),
+ Avx.LoadVector256((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> firstOp, Vector256<Single> secondOp, Vector256<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, Vector256<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplyAdd)}<Single>(Vector256<Single>, Vector256<Single>, Vector256<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddNegated.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddNegated.Double.cs
index 68012d0470..587269bc05 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddNegated.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddNegated.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplyAddNegatedDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplyAddNegatedDouble testClass)
+ {
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ fixed (Vector256<Double>* pFld2 = &_fld2)
+ fixed (Vector256<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddNegated(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld2;
private Vector256<Double> _fld3;
- private SimpleTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplyAddNegatedDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplyAddNegated(
+ Avx.LoadVector256((Double*)(pClsVar1)),
+ Avx.LoadVector256((Double*)(pClsVar2)),
+ Avx.LoadVector256((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplyAddNegated(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplyAddNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddNegated(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddNegated(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplyAddNegatedDouble();
+
+ fixed (Vector256<Double>* pFld1 = &test._fld1)
+ fixed (Vector256<Double>* pFld2 = &test._fld2)
+ fixed (Vector256<Double>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplyAddNegated(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ fixed (Vector256<Double>* pFld2 = &_fld2)
+ fixed (Vector256<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddNegated(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplyAddNegated(
+ Avx.LoadVector256((Double*)(&test._fld1)),
+ Avx.LoadVector256((Double*)(&test._fld2)),
+ Avx.LoadVector256((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> firstOp, Vector256<Double> secondOp, Vector256<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, Vector256<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplyAddNegated)}<Double>(Vector256<Double>, Vector256<Double>, Vector256<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddNegated.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddNegated.Single.cs
index d041c7acd4..f331feac34 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddNegated.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddNegated.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplyAddNegatedSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplyAddNegatedSingle testClass)
+ {
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ fixed (Vector256<Single>* pFld2 = &_fld2)
+ fixed (Vector256<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddNegated(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld2;
private Vector256<Single> _fld3;
- private SimpleTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplyAddNegatedSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplyAddNegated(
+ Avx.LoadVector256((Single*)(pClsVar1)),
+ Avx.LoadVector256((Single*)(pClsVar2)),
+ Avx.LoadVector256((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplyAddNegated(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplyAddNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddNegated(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddNegated(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplyAddNegatedSingle();
+
+ fixed (Vector256<Single>* pFld1 = &test._fld1)
+ fixed (Vector256<Single>* pFld2 = &test._fld2)
+ fixed (Vector256<Single>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplyAddNegated(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ fixed (Vector256<Single>* pFld2 = &_fld2)
+ fixed (Vector256<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddNegated(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplyAddNegated(
+ Avx.LoadVector256((Single*)(&test._fld1)),
+ Avx.LoadVector256((Single*)(&test._fld2)),
+ Avx.LoadVector256((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> firstOp, Vector256<Single> secondOp, Vector256<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, Vector256<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplyAddNegated)}<Single>(Vector256<Single>, Vector256<Single>, Vector256<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddSubtract.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddSubtract.Double.cs
index b3132bafcc..c27c28d990 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddSubtract.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddSubtract.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class AlternatingTernaryOpTest__MultiplyAddSubtractDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(AlternatingTernaryOpTest__MultiplyAddSubtractDouble testClass)
+ {
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ fixed (Vector256<Double>* pFld2 = &_fld2)
+ fixed (Vector256<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddSubtract(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld2;
private Vector256<Double> _fld3;
- private AlternatingTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static AlternatingTernaryOpTest__MultiplyAddSubtractDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new AlternatingTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplyAddSubtract(
+ Avx.LoadVector256((Double*)(pClsVar1)),
+ Avx.LoadVector256((Double*)(pClsVar2)),
+ Avx.LoadVector256((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplyAddSubtract(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplyAddSubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddSubtract(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddSubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddSubtract(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddSubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new AlternatingTernaryOpTest__MultiplyAddSubtractDouble();
+
+ fixed (Vector256<Double>* pFld1 = &test._fld1)
+ fixed (Vector256<Double>* pFld2 = &test._fld2)
+ fixed (Vector256<Double>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplyAddSubtract(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ fixed (Vector256<Double>* pFld2 = &_fld2)
+ fixed (Vector256<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddSubtract(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplyAddSubtract(
+ Avx.LoadVector256((Double*)(&test._fld1)),
+ Avx.LoadVector256((Double*)(&test._fld2)),
+ Avx.LoadVector256((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> firstOp, Vector256<Double> secondOp, Vector256<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, Vector256<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -425,10 +615,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplyAddSubtract)}<Double>(Vector256<Double>, Vector256<Double>, Vector256<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddSubtract.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddSubtract.Single.cs
index 6816cfa4a3..486232aad1 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddSubtract.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplyAddSubtract.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class AlternatingTernaryOpTest__MultiplyAddSubtractSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(AlternatingTernaryOpTest__MultiplyAddSubtractSingle testClass)
+ {
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ fixed (Vector256<Single>* pFld2 = &_fld2)
+ fixed (Vector256<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddSubtract(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld2;
private Vector256<Single> _fld3;
- private AlternatingTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static AlternatingTernaryOpTest__MultiplyAddSubtractSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new AlternatingTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplyAddSubtract(
+ Avx.LoadVector256((Single*)(pClsVar1)),
+ Avx.LoadVector256((Single*)(pClsVar2)),
+ Avx.LoadVector256((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplyAddSubtract(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplyAddSubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddSubtract(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddSubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplyAddSubtract(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplyAddSubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new AlternatingTernaryOpTest__MultiplyAddSubtractSingle();
+
+ fixed (Vector256<Single>* pFld1 = &test._fld1)
+ fixed (Vector256<Single>* pFld2 = &test._fld2)
+ fixed (Vector256<Single>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplyAddSubtract(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ fixed (Vector256<Single>* pFld2 = &_fld2)
+ fixed (Vector256<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplyAddSubtract(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplyAddSubtract(
+ Avx.LoadVector256((Single*)(&test._fld1)),
+ Avx.LoadVector256((Single*)(&test._fld2)),
+ Avx.LoadVector256((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> firstOp, Vector256<Single> secondOp, Vector256<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, Vector256<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -425,10 +615,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplyAddSubtract)}<Single>(Vector256<Single>, Vector256<Single>, Vector256<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtract.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtract.Double.cs
index 26b052518c..259cd8dd81 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtract.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtract.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplySubtractDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplySubtractDouble testClass)
+ {
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ fixed (Vector256<Double>* pFld2 = &_fld2)
+ fixed (Vector256<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtract(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld2;
private Vector256<Double> _fld3;
- private SimpleTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplySubtractDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplySubtract(
+ Avx.LoadVector256((Double*)(pClsVar1)),
+ Avx.LoadVector256((Double*)(pClsVar2)),
+ Avx.LoadVector256((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplySubtract(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplySubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtract(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtract(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplySubtractDouble();
+
+ fixed (Vector256<Double>* pFld1 = &test._fld1)
+ fixed (Vector256<Double>* pFld2 = &test._fld2)
+ fixed (Vector256<Double>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplySubtract(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ fixed (Vector256<Double>* pFld2 = &_fld2)
+ fixed (Vector256<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtract(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplySubtract(
+ Avx.LoadVector256((Double*)(&test._fld1)),
+ Avx.LoadVector256((Double*)(&test._fld2)),
+ Avx.LoadVector256((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> firstOp, Vector256<Double> secondOp, Vector256<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, Vector256<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplySubtract)}<Double>(Vector256<Double>, Vector256<Double>, Vector256<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtract.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtract.Single.cs
index 0c81d6bd71..77d9f71f1e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtract.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtract.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplySubtractSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplySubtractSingle testClass)
+ {
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ fixed (Vector256<Single>* pFld2 = &_fld2)
+ fixed (Vector256<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtract(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld2;
private Vector256<Single> _fld3;
- private SimpleTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplySubtractSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplySubtract(
+ Avx.LoadVector256((Single*)(pClsVar1)),
+ Avx.LoadVector256((Single*)(pClsVar2)),
+ Avx.LoadVector256((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplySubtract(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplySubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtract(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtract(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtract(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplySubtractSingle();
+
+ fixed (Vector256<Single>* pFld1 = &test._fld1)
+ fixed (Vector256<Single>* pFld2 = &test._fld2)
+ fixed (Vector256<Single>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplySubtract(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ fixed (Vector256<Single>* pFld2 = &_fld2)
+ fixed (Vector256<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtract(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplySubtract(
+ Avx.LoadVector256((Single*)(&test._fld1)),
+ Avx.LoadVector256((Single*)(&test._fld2)),
+ Avx.LoadVector256((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> firstOp, Vector256<Single> secondOp, Vector256<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, Vector256<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplySubtract)}<Single>(Vector256<Single>, Vector256<Single>, Vector256<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractAdd.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractAdd.Double.cs
index 964006f6ad..44f76e1761 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractAdd.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractAdd.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class AlternatingTernaryOpTest__MultiplySubtractAddDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(AlternatingTernaryOpTest__MultiplySubtractAddDouble testClass)
+ {
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ fixed (Vector256<Double>* pFld2 = &_fld2)
+ fixed (Vector256<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractAdd(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld2;
private Vector256<Double> _fld3;
- private AlternatingTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static AlternatingTernaryOpTest__MultiplySubtractAddDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new AlternatingTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplySubtractAdd(
+ Avx.LoadVector256((Double*)(pClsVar1)),
+ Avx.LoadVector256((Double*)(pClsVar2)),
+ Avx.LoadVector256((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplySubtractAdd(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplySubtractAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractAdd(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractAdd(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new AlternatingTernaryOpTest__MultiplySubtractAddDouble();
+
+ fixed (Vector256<Double>* pFld1 = &test._fld1)
+ fixed (Vector256<Double>* pFld2 = &test._fld2)
+ fixed (Vector256<Double>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplySubtractAdd(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ fixed (Vector256<Double>* pFld2 = &_fld2)
+ fixed (Vector256<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractAdd(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplySubtractAdd(
+ Avx.LoadVector256((Double*)(&test._fld1)),
+ Avx.LoadVector256((Double*)(&test._fld2)),
+ Avx.LoadVector256((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> firstOp, Vector256<Double> secondOp, Vector256<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, Vector256<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -425,10 +615,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplySubtractAdd)}<Double>(Vector256<Double>, Vector256<Double>, Vector256<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractAdd.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractAdd.Single.cs
index 930138a5f7..a696aa8c78 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractAdd.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractAdd.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class AlternatingTernaryOpTest__MultiplySubtractAddSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(AlternatingTernaryOpTest__MultiplySubtractAddSingle testClass)
+ {
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ fixed (Vector256<Single>* pFld2 = &_fld2)
+ fixed (Vector256<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractAdd(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld2;
private Vector256<Single> _fld3;
- private AlternatingTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static AlternatingTernaryOpTest__MultiplySubtractAddSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new AlternatingTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplySubtractAdd(
+ Avx.LoadVector256((Single*)(pClsVar1)),
+ Avx.LoadVector256((Single*)(pClsVar2)),
+ Avx.LoadVector256((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplySubtractAdd(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplySubtractAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractAdd(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractAdd(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractAdd(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new AlternatingTernaryOpTest__MultiplySubtractAddSingle();
+
+ fixed (Vector256<Single>* pFld1 = &test._fld1)
+ fixed (Vector256<Single>* pFld2 = &test._fld2)
+ fixed (Vector256<Single>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplySubtractAdd(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ fixed (Vector256<Single>* pFld2 = &_fld2)
+ fixed (Vector256<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractAdd(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplySubtractAdd(
+ Avx.LoadVector256((Single*)(&test._fld1)),
+ Avx.LoadVector256((Single*)(&test._fld2)),
+ Avx.LoadVector256((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> firstOp, Vector256<Single> secondOp, Vector256<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, Vector256<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -425,10 +615,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplySubtractAdd)}<Single>(Vector256<Single>, Vector256<Single>, Vector256<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractNegated.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractNegated.Double.cs
index 365f1d0202..3adebd7bb8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractNegated.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractNegated.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplySubtractNegatedDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Double> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref _clsVar3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Double>, byte>(ref testStruct._fld3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Double>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplySubtractNegatedDouble testClass)
+ {
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ fixed (Vector256<Double>* pFld2 = &_fld2)
+ fixed (Vector256<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractNegated(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Double> _fld2;
private Vector256<Double> _fld3;
- private SimpleTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplySubtractNegatedDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplySubtractNegated(
+ Avx.LoadVector256((Double*)(pClsVar1)),
+ Avx.LoadVector256((Double*)(pClsVar2)),
+ Avx.LoadVector256((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Double>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplySubtractNegated(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Double>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplySubtractNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractNegated(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractNegated(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Double*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplySubtractNegatedDouble();
+
+ fixed (Vector256<Double>* pFld1 = &test._fld1)
+ fixed (Vector256<Double>* pFld2 = &test._fld2)
+ fixed (Vector256<Double>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplySubtractNegated(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Double>* pFld1 = &_fld1)
+ fixed (Vector256<Double>* pFld2 = &_fld2)
+ fixed (Vector256<Double>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractNegated(
+ Avx.LoadVector256((Double*)(pFld1)),
+ Avx.LoadVector256((Double*)(pFld2)),
+ Avx.LoadVector256((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplySubtractNegated(
+ Avx.LoadVector256((Double*)(&test._fld1)),
+ Avx.LoadVector256((Double*)(&test._fld2)),
+ Avx.LoadVector256((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Double> firstOp, Vector256<Double> secondOp, Vector256<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Double> op1, Vector256<Double> op2, Vector256<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplySubtractNegated)}<Double>(Vector256<Double>, Vector256<Double>, Vector256<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractNegated.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractNegated.Single.cs
index a0ac1c1a2d..e8fcca3c9d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractNegated.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Fma_Vector256/MultiplySubtractNegated.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Avx.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Avx.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__MultiplySubtractNegatedSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector256<Single> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref _clsVar3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector256<Single>, byte>(ref testStruct._fld3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector256<Single>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__MultiplySubtractNegatedSingle testClass)
+ {
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ fixed (Vector256<Single>* pFld2 = &_fld2)
+ fixed (Vector256<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractNegated(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 32;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector256<Single> _fld2;
private Vector256<Single> _fld3;
- private SimpleTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__MultiplySubtractNegatedSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Fma.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector256<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector256<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector256<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Fma.MultiplySubtractNegated(
+ Avx.LoadVector256((Single*)(pClsVar1)),
+ Avx.LoadVector256((Single*)(pClsVar2)),
+ Avx.LoadVector256((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector256<Single>>(_dataTable.inArray3Ptr);
- var result = Fma.MultiplySubtractNegated(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector256<Single>>(_dataTable.inArray3Ptr);
+ var result = Fma.MultiplySubtractNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadVector256((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractNegated(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadVector256((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadVector256((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray3Ptr));
- var result = Fma.MultiplySubtractNegated(firstOp, secondOp, thirdOp);
+ var op1 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Avx.LoadAlignedVector256((Single*)(_dataTable.inArray3Ptr));
+ var result = Fma.MultiplySubtractNegated(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__MultiplySubtractNegatedSingle();
+
+ fixed (Vector256<Single>* pFld1 = &test._fld1)
+ fixed (Vector256<Single>* pFld2 = &test._fld2)
+ fixed (Vector256<Single>* pFld3 = &test._fld3)
+ {
+ var result = Fma.MultiplySubtractNegated(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector256<Single>* pFld1 = &_fld1)
+ fixed (Vector256<Single>* pFld2 = &_fld2)
+ fixed (Vector256<Single>* pFld3 = &_fld3)
+ {
+ var result = Fma.MultiplySubtractNegated(
+ Avx.LoadVector256((Single*)(pFld1)),
+ Avx.LoadVector256((Single*)(pFld2)),
+ Avx.LoadVector256((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Fma.MultiplySubtractNegated(
+ Avx.LoadVector256((Single*)(&test._fld1)),
+ Avx.LoadVector256((Single*)(&test._fld2)),
+ Avx.LoadVector256((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector256<Single> firstOp, Vector256<Single> secondOp, Vector256<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector256<Single> op1, Vector256<Single> op2, Vector256<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector256<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector256<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector256<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Fma)}.{nameof(Fma.MultiplySubtractNegated)}<Single>(Vector256<Single>, Vector256<Single>, Vector256<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/AlternatingBinOpTest_DataTable.cs b/tests/src/JIT/HardwareIntrinsics/X86/Shared/AlternatingBinOpTest_DataTable.cs
deleted file mode 100644
index 6f87416366..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/AlternatingBinOpTest_DataTable.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace JIT.HardwareIntrinsics.X86
-{
- public unsafe struct AlternatingBinaryOpTest__DataTable<TResult, TOp1, TOp2> : IDisposable
- where TResult : struct
- where TOp1 : struct
- where TOp2 : struct
- {
- private byte[] inArray1;
- private byte[] inArray2;
- private byte[] outArray;
-
- private GCHandle inHandle1;
- private GCHandle inHandle2;
- private GCHandle outHandle;
-
- private ulong alignment;
-
- public AlternatingBinaryOpTest__DataTable(TOp1[] inArray1, TOp2[] inArray2, TResult[] outArray, int alignment)
- {
- int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<TOp1>();
- int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<TOp2>();
- int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<TResult>();
- if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
- {
- throw new ArgumentException("Invalid value of alignment");
- }
-
- this.inArray1 = new byte[alignment * 2];
- this.inArray2 = new byte[alignment * 2];
- this.outArray = new byte[alignment * 2];
-
- this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
- this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
- this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
-
- this.alignment = (ulong)alignment;
-
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<TOp1, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<TOp2, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
- }
-
- public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
- public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
- public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
-
- public void Dispose()
- {
- inHandle1.Free();
- inHandle2.Free();
- outHandle.Free();
- }
-
- private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
- {
- return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/AlternatingTernOpTest_DataTable.cs b/tests/src/JIT/HardwareIntrinsics/X86/Shared/AlternatingTernOpTest_DataTable.cs
deleted file mode 100644
index d9e57c4d6e..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/AlternatingTernOpTest_DataTable.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace JIT.HardwareIntrinsics.X86
-{
- public unsafe struct AlternatingTernaryOpTest__DataTable<TResult, TOp1, TOp2, TOp3> : IDisposable
- where TResult : struct
- where TOp1 : struct
- where TOp2 : struct
- where TOp3 : struct
- {
- private byte[] inArray1;
- private byte[] inArray2;
- private byte[] inArray3;
- private byte[] outArray;
-
- private GCHandle inHandle1;
- private GCHandle inHandle2;
- private GCHandle inHandle3;
- private GCHandle outHandle;
-
- private ulong alignment;
-
- public AlternatingTernaryOpTest__DataTable(TOp1[] inArray1, TOp2[] inArray2, TOp3[] inArray3, TResult[] outArray, int alignment)
- {
- int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<TOp1>();
- int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<TOp2>();
- int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<TOp3>();
- int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<TResult>();
- if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 ||
- (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
- {
- throw new ArgumentException("Invalid value of alignment");
- }
-
- this.inArray1 = new byte[alignment * 2];
- this.inArray2 = new byte[alignment * 2];
- this.inArray3 = new byte[alignment * 2];
- this.outArray = new byte[alignment * 2];
-
- this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
- this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
- this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
- this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
-
- this.alignment = (ulong)alignment;
-
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<TOp1, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<TOp2, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<TOp3, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
- }
-
- public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
- public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
- public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
- public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
-
- public void Dispose()
- {
- inHandle1.Free();
- inHandle2.Free();
- inHandle3.Free();
- outHandle.Free();
- }
-
- private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
- {
- return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanBinOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanBinOpTest.template
deleted file mode 100644
index 35a8f06328..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanBinOpTest.template
+++ /dev/null
@@ -1,392 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/******************************************************************************
- * This file is auto-generated from a template file by the GenerateTests.csx *
- * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
- * changes, please update the corresponding template and run according to the *
- * directions listed in the file. *
- ******************************************************************************/
-
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace JIT.HardwareIntrinsics.X86
-{
- public static partial class Program
- {
- private static void {Method}{RetBaseType}()
- {
- var test = new BooleanBinaryOpTest__{Method}{RetBaseType}();
-
- if (test.IsSupported)
- {
- // Validates basic functionality works, using Unsafe.Read
- test.RunBasicScenario_UnsafeRead();
-
- if ({LoadIsa}.IsSupported)
- {
- // Validates basic functionality works, using Load
- test.RunBasicScenario_Load();
-
- // Validates basic functionality works, using LoadAligned
- test.RunBasicScenario_LoadAligned();
- }
-
- // Validates calling via reflection works, using Unsafe.Read
- test.RunReflectionScenario_UnsafeRead();
-
- if ({LoadIsa}.IsSupported)
- {
- // Validates calling via reflection works, using Load
- test.RunReflectionScenario_Load();
-
- // Validates calling via reflection works, using LoadAligned
- test.RunReflectionScenario_LoadAligned();
- }
-
- // Validates passing a static member works
- test.RunClsVarScenario();
-
- // Validates passing a local works, using Unsafe.Read
- test.RunLclVarScenario_UnsafeRead();
-
- if ({LoadIsa}.IsSupported)
- {
- // Validates passing a local works, using Load
- test.RunLclVarScenario_Load();
-
- // Validates passing a local works, using LoadAligned
- test.RunLclVarScenario_LoadAligned();
- }
-
- // Validates passing the field of a local class works
- test.RunClassLclFldScenario();
-
- // Validates passing an instance member of a class works
- test.RunClassFldScenario();
-
- // Validates passing the field of a local struct works
- test.RunStructLclFldScenario();
-
- // Validates passing an instance member of a struct works
- test.RunStructFldScenario();
- }
- else
- {
- // Validates we throw on unsupported hardware
- test.RunUnsupportedScenario();
- }
-
- if (!test.Succeeded)
- {
- throw new Exception("One or more scenarios did not complete as expected.");
- }
- }
- }
-
- public sealed unsafe class BooleanBinaryOpTest__{Method}{RetBaseType}
- {
- private struct TestStruct
- {
- public {Op1VectorType}<{Op1BaseType}> _fld1;
- public {Op2VectorType}<{Op2BaseType}> _fld2;
-
- public static TestStruct Create()
- {
- var testStruct = new TestStruct();
-
- for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
-
- return testStruct;
- }
-
- public void RunStructFldScenario(BooleanBinaryOpTest__{Method}{RetBaseType} testClass)
- {
- var result = {Isa}.{Method}(_fld1, _fld2);
- testClass.ValidateResult(_fld1, _fld2, result);
- }
- }
-
- private static readonly int LargestVectorSize = {LargestVectorSize};
-
- private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType});
- private static readonly int Op2ElementCount = Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType});
-
- private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount];
- private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount];
-
- private static {Op1VectorType}<{Op1BaseType}> _clsVar1;
- private static {Op2VectorType}<{Op2BaseType}> _clsVar2;
-
- private {Op1VectorType}<{Op1BaseType}> _fld1;
- private {Op2VectorType}<{Op2BaseType}> _fld2;
-
- private BooleanBinaryOpTest__DataTable<{Op1BaseType}, {Op2BaseType}> _dataTable;
-
- static BooleanBinaryOpTest__{Method}{RetBaseType}()
- {
- for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _clsVar2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
- }
-
- public BooleanBinaryOpTest__{Method}{RetBaseType}()
- {
- Succeeded = true;
-
- for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
-
- for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- _dataTable = new BooleanBinaryOpTest__DataTable<{Op1BaseType}, {Op2BaseType}>(_data1, _data2, LargestVectorSize);
- }
-
- public bool IsSupported => {Isa}.IsSupported;
-
- public bool Succeeded { get; set; }
-
- public void RunBasicScenario_UnsafeRead()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
-
- var result = {Isa}.{Method}(
- Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr),
- Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr)
- );
-
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
- }
-
- public void RunBasicScenario_Load()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
-
- var result = {Isa}.{Method}(
- {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr))
- );
-
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
- }
-
- public void RunBasicScenario_LoadAligned()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
-
- var result = {Isa}.{Method}(
- {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr))
- );
-
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
- }
-
- public void RunReflectionScenario_UnsafeRead()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
-
- var method = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
- Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr),
- Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr)
- });
-
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
- }
-
- public void RunReflectionScenario_Load()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
-
- var method = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
- {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr))
- });
-
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
- }
-
- public void RunReflectionScenario_LoadAligned()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
-
- var method = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
- {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr))
- });
-
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
- }
-
- public void RunClsVarScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
-
- var result = {Isa}.{Method}(
- _clsVar1,
- _clsVar2
- );
-
- ValidateResult(_clsVar1, _clsVar2, result);
- }
-
- public void RunLclVarScenario_UnsafeRead()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
-
- var left = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr);
- var result = {Isa}.{Method}(left, right);
-
- ValidateResult(left, right, result);
- }
-
- public void RunLclVarScenario_Load()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
-
- var left = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
- var right = {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
- var result = {Isa}.{Method}(left, right);
-
- ValidateResult(left, right, result);
- }
-
- public void RunLclVarScenario_LoadAligned()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
-
- var left = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
- var right = {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
- var result = {Isa}.{Method}(left, right);
-
- ValidateResult(left, right, result);
- }
-
- public void RunClassLclFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
-
- var test = new BooleanBinaryOpTest__{Method}{RetBaseType}();
- var result = {Isa}.{Method}(test._fld1, test._fld2);
-
- ValidateResult(test._fld1, test._fld2, result);
- }
-
- public void RunClassFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
-
- var result = {Isa}.{Method}(_fld1, _fld2);
-
- ValidateResult(_fld1, _fld2, result);
- }
-
- public void RunStructLclFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
-
- var test = TestStruct.Create();
- var result = {Isa}.{Method}(test._fld1, test._fld2);
- ValidateResult(test._fld1, test._fld2, result);
- }
-
- public void RunStructFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
-
- var test = TestStruct.Create();
- test.RunStructFldScenario(this);
- }
-
- public void RunUnsupportedScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
-
- bool succeeded = false;
-
- try
- {
- RunBasicScenario_UnsafeRead();
- }
- catch (PlatformNotSupportedException)
- {
- succeeded = true;
- }
-
- if (!succeeded)
- {
- Succeeded = false;
- }
- }
-
- private void ValidateResult({Op1VectorType}<{Op1BaseType}> left, {Op2VectorType}<{Op2BaseType}> right, bool result, [CallerMemberName] string method = "")
- {
- {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
- {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
-
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), right);
-
- ValidateResult(inArray1, inArray2, result, method);
- }
-
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
- {
- {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
- {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
-
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
-
- ValidateResult(inArray1, inArray2, result, method);
- }
-
- private void ValidateResult({Op1BaseType}[] left, {Op2BaseType}[] right, bool result, [CallerMemberName] string method = "")
- {
- var expectedResult = true;
-
- for (var i = 0; i < Op1ElementCount; i++)
- {
- expectedResult &= ({ValidateFirstResult});
- }
-
- if (expectedResult != result)
- {
- TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
- TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
- TestLibrary.TestFramework.LogInformation(string.Empty);
-
- Succeeded = false;
- }
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanBinOpTest_DataTable.cs b/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanBinOpTest_DataTable.cs
deleted file mode 100644
index b2683ced77..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanBinOpTest_DataTable.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace JIT.HardwareIntrinsics.X86
-{
- public unsafe struct BooleanBinaryOpTest__DataTable<TOp1, TOp2> : IDisposable
- where TOp1 : struct
- where TOp2 : struct
- {
- private byte[] inArray1;
- private byte[] inArray2;
-
- private GCHandle inHandle1;
- private GCHandle inHandle2;
-
- private ulong alignment;
-
- public BooleanBinaryOpTest__DataTable(TOp1[] inArray1, TOp2[] inArray2, int alignment)
- {
- int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<TOp1>();
- int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<TOp2>();
- if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
- {
- throw new ArgumentException("Invalid value of alignment");
- }
-
- this.inArray1 = new byte[alignment * 2];
- this.inArray2 = new byte[alignment * 2];
-
- this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
- this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
-
- this.alignment = (ulong)alignment;
-
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<TOp1, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<TOp2, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
- }
-
- public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
- public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
-
- public void Dispose()
- {
- inHandle1.Free();
- inHandle2.Free();
- }
-
- private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
- {
- return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanCmpOpTest_DataTable.cs b/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanCmpOpTest_DataTable.cs
deleted file mode 100644
index 557b560d54..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanCmpOpTest_DataTable.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace JIT.HardwareIntrinsics.X86
-{
- public unsafe struct BooleanComparisonOpTest__DataTable<TOp1, TOp2> : IDisposable
- where TOp1 : struct
- where TOp2 : struct
- {
- private byte[] inArray1;
- private byte[] inArray2;
-
- private GCHandle inHandle1;
- private GCHandle inHandle2;
-
- private ulong alignment;
-
- public BooleanComparisonOpTest__DataTable(TOp1[] inArray1, TOp2[] inArray2, int alignment)
- {
- int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<TOp1>();
- int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<TOp2>();
- if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
- {
- throw new ArgumentException("Invalid value of alignment");
- }
-
- this.inArray1 = new byte[alignment * 2];
- this.inArray2 = new byte[alignment * 2];
-
- this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
- this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
-
- this.alignment = (ulong)alignment;
-
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<TOp1, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<TOp2, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
- }
-
- public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
- public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
-
- public void Dispose()
- {
- inHandle1.Free();
- inHandle2.Free();
- }
-
- private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
- {
- return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanTwoCmpOpTest_DataTable.cs b/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanTwoCmpOpTest_DataTable.cs
deleted file mode 100644
index f2ab635c56..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanTwoCmpOpTest_DataTable.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace JIT.HardwareIntrinsics.X86
-{
- public unsafe struct BooleanTwoComparisonOpTest__DataTable<TOp1, TOp2> : IDisposable
- where TOp1 : struct
- where TOp2 : struct
- {
- private byte[] inArray1;
- private byte[] inArray2;
-
- private GCHandle inHandle1;
- private GCHandle inHandle2;
-
- private ulong alignment;
-
- public BooleanTwoComparisonOpTest__DataTable(TOp1[] inArray1, TOp2[] inArray2, int alignment)
- {
- int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<TOp1>();
- int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<TOp2>();
- if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
- {
- throw new ArgumentException("Invalid value of alignment");
- }
-
- this.inArray1 = new byte[alignment * 2];
- this.inArray2 = new byte[alignment * 2];
-
- this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
- this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
-
- this.alignment = (ulong)alignment;
-
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<TOp1, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<TOp2, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
- }
-
- public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
- public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
-
- public void Dispose()
- {
- inHandle1.Free();
- inHandle2.Free();
- }
-
- private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
- {
- return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanUnOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanUnOpTest.template
deleted file mode 100644
index 5924e48d39..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanUnOpTest.template
+++ /dev/null
@@ -1,354 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/******************************************************************************
- * This file is auto-generated from a template file by the GenerateTests.csx *
- * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
- * changes, please update the corresponding template and run according to the *
- * directions listed in the file. *
- ******************************************************************************/
-
-using System;
-using System.Linq;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace JIT.HardwareIntrinsics.X86
-{
- public static partial class Program
- {
- private static void {Method}{RetBaseType}()
- {
- var test = new BooleanUnaryOpTest__{Method}{RetBaseType}();
-
- if (test.IsSupported)
- {
- // Validates basic functionality works, using Unsafe.Read
- test.RunBasicScenario_UnsafeRead();
-
- if ({LoadIsa}.IsSupported)
- {
- // Validates basic functionality works, using Load
- test.RunBasicScenario_Load();
-
- // Validates basic functionality works, using LoadAligned
- test.RunBasicScenario_LoadAligned();
- }
-
- // Validates calling via reflection works, using Unsafe.Read
- test.RunReflectionScenario_UnsafeRead();
-
- if ({LoadIsa}.IsSupported)
- {
- // Validates calling via reflection works, using Load
- test.RunReflectionScenario_Load();
-
- // Validates calling via reflection works, using LoadAligned
- test.RunReflectionScenario_LoadAligned();
- }
-
- // Validates passing a static member works
- test.RunClsVarScenario();
-
- // Validates passing a local works, using Unsafe.Read
- test.RunLclVarScenario_UnsafeRead();
-
- if ({LoadIsa}.IsSupported)
- {
- // Validates passing a local works, using Load
- test.RunLclVarScenario_Load();
-
- // Validates passing a local works, using LoadAligned
- test.RunLclVarScenario_LoadAligned();
- }
-
- // Validates passing the field of a local class works
- test.RunClassLclFldScenario();
-
- // Validates passing an instance member of a class works
- test.RunClassFldScenario();
-
- // Validates passing the field of a local struct works
- test.RunStructLclFldScenario();
-
- // Validates passing an instance member of a struct works
- test.RunStructFldScenario();
- }
- else
- {
- // Validates we throw on unsupported hardware
- test.RunUnsupportedScenario();
- }
-
- if (!test.Succeeded)
- {
- throw new Exception("One or more scenarios did not complete as expected.");
- }
- }
- }
-
- public sealed unsafe class BooleanUnaryOpTest__{Method}{RetBaseType}
- {
- private struct TestStruct
- {
- public {Op1VectorType}<{Op1BaseType}> _fld;
-
- public static TestStruct Create()
- {
- var testStruct = new TestStruct();
-
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
-
- return testStruct;
- }
-
- public void RunStructFldScenario(BooleanUnaryOpTest__{Method}{RetBaseType} testClass)
- {
- var result = {Isa}.{Method}(_fld);
- testClass.ValidateResult(_fld, result);
- }
- }
-
- private static readonly int LargestVectorSize = {LargestVectorSize};
-
- private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType});
-
- private static {Op1BaseType}[] _data = new {Op1BaseType}[Op1ElementCount];
-
- private static {Op1VectorType}<{Op1BaseType}> _clsVar;
-
- private {Op1VectorType}<{Op1BaseType}> _fld;
-
- private BooleanUnaryOpTest__DataTable<{Op1BaseType}> _dataTable;
-
- static BooleanUnaryOpTest__{Method}{RetBaseType}()
- {
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- }
-
- public BooleanUnaryOpTest__{Method}{RetBaseType}()
- {
- Succeeded = true;
-
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
-
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; }
- _dataTable = new BooleanUnaryOpTest__DataTable<{Op1BaseType}>(_data, LargestVectorSize);
- }
-
- public bool IsSupported => {Isa}.IsSupported;
-
- public bool Succeeded { get; set; }
-
- public void RunBasicScenario_UnsafeRead()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
-
- var result = {Isa}.{Method}(
- Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr)
- );
-
- ValidateResult(_dataTable.inArrayPtr, result);
- }
-
- public void RunBasicScenario_Load()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
-
- var result = {Isa}.{Method}(
- {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr))
- );
-
- ValidateResult(_dataTable.inArrayPtr, result);
- }
-
- public void RunBasicScenario_LoadAligned()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
-
- var result = {Isa}.{Method}(
- {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr))
- );
-
- ValidateResult(_dataTable.inArrayPtr, result);
- }
-
- public void RunReflectionScenario_UnsafeRead()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
-
- var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>) })
- .Invoke(null, new object[] {
- Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr)
- });
-
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
- }
-
- public void RunReflectionScenario_Load()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
-
- var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>) })
- .Invoke(null, new object[] {
- {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr))
- });
-
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
- }
-
- public void RunReflectionScenario_LoadAligned()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
-
- var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>) })
- .Invoke(null, new object[] {
- {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr))
- });
-
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
- }
-
- public void RunClsVarScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
-
- var result = {Isa}.{Method}(
- _clsVar
- );
-
- ValidateResult(_clsVar, result);
- }
-
- public void RunLclVarScenario_UnsafeRead()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
-
- var value = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr);
- var result = {Isa}.{Method}(value);
-
- ValidateResult(value, result);
- }
-
- public void RunLclVarScenario_Load()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
-
- var value = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr));
- var result = {Isa}.{Method}(value);
-
- ValidateResult(value, result);
- }
-
- public void RunLclVarScenario_LoadAligned()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
-
- var value = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr));
- var result = {Isa}.{Method}(value);
-
- ValidateResult(value, result);
- }
-
- public void RunClassLclFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
-
- var test = new BooleanUnaryOpTest__{Method}{RetBaseType}();
- var result = {Isa}.{Method}(test._fld);
-
- ValidateResult(test._fld, result);
- }
-
- public void RunClassFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
-
- var result = {Isa}.{Method}(_fld);
-
- ValidateResult(_fld, result);
- }
-
- public void RunStructLclFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
-
- var test = TestStruct.Create();
- var result = {Isa}.{Method}(test._fld);
- ValidateResult(test._fld, result);
- }
-
- public void RunStructFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
-
- var test = TestStruct.Create();
- test.RunStructFldScenario(this);
- }
-
- public void RunUnsupportedScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
-
- bool succeeded = false;
-
- try
- {
- RunBasicScenario_UnsafeRead();
- }
- catch (PlatformNotSupportedException)
- {
- succeeded = true;
- }
-
- if (!succeeded)
- {
- Succeeded = false;
- }
- }
-
- private void ValidateResult({Op1VectorType}<{Op1BaseType}> value, bool result, [CallerMemberName] string method = "")
- {
- {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount];
-
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray[0]), value);
-
- ValidateResult(inArray, result, method);
- }
-
- private void ValidateResult(void* value, bool result, [CallerMemberName] string method = "")
- {
- {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount];
-
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(value), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
-
- ValidateResult(inArray, result, method);
- }
-
- private void ValidateResult({Op1BaseType}[] value, bool result, [CallerMemberName] string method = "")
- {
- var expectedResult = true;
-
- for (var i = 0; i < Op1ElementCount; i++)
- {
- expectedResult &= ({ValidateFirstResult});
- }
-
- if (expectedResult != result)
- {
- TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
- TestLibrary.TestFramework.LogInformation(string.Empty);
-
- Succeeded = false;
- }
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanUnOpTest_DataTable.cs b/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanUnOpTest_DataTable.cs
deleted file mode 100644
index a94532413d..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanUnOpTest_DataTable.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace JIT.HardwareIntrinsics.X86
-{
- public unsafe struct BooleanUnaryOpTest__DataTable<TOp1> : IDisposable
- where TOp1 : struct
- {
- private byte[] inArray;
-
- private GCHandle inHandle;
-
- private ulong alignment;
-
- public BooleanUnaryOpTest__DataTable(TOp1[] inArray, int alignment)
- {
- int sizeOfinArray = inArray.Length * Unsafe.SizeOf<TOp1>();
- if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray)
- {
- throw new ArgumentException("Invalid value of alignment");
- }
- this.inArray = new byte[alignment * 2];
-
- this.inHandle = GCHandle.Alloc(this.inArray, GCHandleType.Pinned);
-
- this.alignment = (ulong)alignment;
-
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArrayPtr), ref Unsafe.As<TOp1, byte>(ref inArray[0]), (uint)sizeOfinArray);
- }
-
- public void* inArrayPtr => Align((byte*)(inHandle.AddrOfPinnedObject().ToPointer()), alignment);
-
- public void Dispose()
- {
- inHandle.Free();
- }
-
- private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
- {
- return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx b/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx
index ee4460283a..7cbf8b7551 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/GenerateTests.csx
@@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
// DIRECTIONS:
// This file isn't very robust and makes several assumptions
@@ -19,6 +20,103 @@ using System.IO;
// You can support a new Isa by creating a new array and adding a new
// "ProcessInputs" call at the bottom of the script.
+private const string AlternatingOpTest_ValidationLogic = @"for (var i = 0; i < RetElementCount; i += 2)
+ {
+ if ({ValidateFirstResult})
+ {
+ succeeded = false;
+ break;
+ }
+
+ if ({ValidateRemainingResults})
+ {
+ succeeded = false;
+ break;
+ }
+ }";
+
+private const string BooleanCmpTest_ValidationLogic = @"if ({ValidateFirstResult})
+ {
+ succeeded = false;
+ }";
+
+private const string BooleanTwoCmpTest_ValidationLogic = @"var expectedResult1 = true;
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ expectedResult1 &= ({ValidateFirstResult});
+ }
+
+ var expectedResult2 = true;
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ expectedResult2 &= ({ValidateRemainingResults});
+ }
+
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);";
+
+private const string BooleanOpTest_ValidationLogic = @"var expectedResult = true;
+
+ for (var i = 0; i < Op1ElementCount; i++)
+ {
+ expectedResult &= ({ValidateFirstResult});
+ }
+
+ succeeded = (expectedResult == result);";
+
+private const string HorizontalOpTest_ValidationLogic = @"for (var outer = 0; outer < (LargestVectorSize / 16); outer++)
+ {
+ for (var inner = 0; inner < (8 / sizeof({RetBaseType})); inner++)
+ {
+ var i1 = (outer * (16 / sizeof({RetBaseType}))) + inner;
+ var i2 = i1 + (8 / sizeof({RetBaseType}));
+ var i3 = (outer * (16 / sizeof({RetBaseType}))) + (inner * 2);
+
+ if ({ValidateFirstResult})
+ {
+ succeeded = false;
+ break;
+ }
+
+ if ({ValidateRemainingResults})
+ {
+ succeeded = false;
+ break;
+ }
+ }
+ }";
+
+private const string SimpleOpTest_ValidationLogic = @"if ({ValidateFirstResult})
+ {
+ succeeded = false;
+ }
+ else
+ {
+ for (var i = 1; i < RetElementCount; i++)
+ {
+ if ({ValidateRemainingResults})
+ {
+ succeeded = false;
+ break;
+ }
+ }
+ }";
+
+private static readonly (string templateFileName, string outputTemplateName, Dictionary<string, string> templateData)[] Templates = new[]
+{
+ ("_BinaryOpTestTemplate.template", "AlternatingBinOpTest.template", new Dictionary<string, string> { ["TemplateName"] = "Alternating", ["TemplateValidationLogic"] = AlternatingOpTest_ValidationLogic }),
+ ("_BinaryOpTestTemplate.template", "HorizontalBinOpTest.template", new Dictionary<string, string> { ["TemplateName"] = "Horizontal", ["TemplateValidationLogic"] = HorizontalOpTest_ValidationLogic }),
+ ("_BinaryOpTestTemplate.template", "SimpleBinOpTest.template", new Dictionary<string, string> { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }),
+ ("_BooleanBinaryOpTestTemplate.template", "BooleanBinOpTest.template", new Dictionary<string, string> { ["TemplateName"] = "Boolean", ["TemplateValidationLogic"] = BooleanOpTest_ValidationLogic }),
+ ("_BooleanBinaryOpTestTemplate.template", "BooleanCmpOpTest.template", new Dictionary<string, string> { ["TemplateName"] = "Boolean", ["TemplateValidationLogic"] = BooleanCmpTest_ValidationLogic }),
+ ("_BooleanBinaryOpTestTemplate.template", "BooleanTwoCmpOpTest.template", new Dictionary<string, string> { ["TemplateName"] = "Boolean", ["TemplateValidationLogic"] = BooleanTwoCmpTest_ValidationLogic }),
+ ("_BooleanUnaryOpTestTemplate.template", "BooleanUnOpTest.template", new Dictionary<string, string> { ["TemplateName"] = "Boolean", ["TemplateValidationLogic"] = BooleanOpTest_ValidationLogic }),
+ ("_TernaryOpTestTemplate.template", "AlternatingTernOpTest.template", new Dictionary<string, string> { ["TemplateName"] = "Alternating", ["TemplateValidationLogic"] = AlternatingOpTest_ValidationLogic }),
+ ("_TernaryOpTestTemplate.template", "SimpleTernOpTest.template", new Dictionary<string, string> { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }),
+ ("_UnaryOpTestTemplate.template", "SimpleUnOpTest.template", new Dictionary<string, string> { ["TemplateName"] = "Simple", ["TemplateValidationLogic"] = SimpleOpTest_ValidationLogic }),
+};
+
private static readonly (string templateFileName, Dictionary<string, string> templateData)[] SseInputs = new []
{
("SimpleBinOpTest.template", new Dictionary<string, string> { ["Isa"] = "Sse", ["LoadIsa"] = "Sse", ["Method"] = "Add", ["RetVectorType"] = "Vector128", ["RetBaseType"] = "Single", ["Op1VectorType"] = "Vector128", ["Op1BaseType"] = "Single", ["Op2VectorType"] = "Vector128", ["Op2BaseType"] = "Single", ["LargestVectorSize"] = "16", ["NextValueOp1"] = "TestLibrary.Generator.GetSingle()", ["NextValueOp2"] = "TestLibrary.Generator.GetSingle()", ["ValidateFirstResult"] = "BitConverter.SingleToInt32Bits(left[0] + right[0]) != BitConverter.SingleToInt32Bits(result[0])", ["ValidateRemainingResults"] = "BitConverter.SingleToInt32Bits(left[i] + right[i]) != BitConverter.SingleToInt32Bits(result[i])"}),
@@ -1243,7 +1341,22 @@ private static void ProcessInput(StreamWriter testListFile, string groupName, (s
}
var testFileName = Path.Combine("..", groupName, $"{testName}.cs");
- var template = File.ReadAllText(input.templateFileName);
+ var matchingTemplate = Templates.Where((t) => t.outputTemplateName.Equals(input.templateFileName)).SingleOrDefault();
+ var template = string.Empty;
+
+ if (matchingTemplate.templateFileName is null)
+ {
+ template = File.ReadAllText(input.templateFileName);
+ }
+ else
+ {
+ template = File.ReadAllText(matchingTemplate.templateFileName);
+
+ foreach (var kvp in matchingTemplate.templateData)
+ {
+ template = template.Replace($"{{{kvp.Key}}}", kvp.Value);
+ }
+ }
foreach (var kvp in input.templateData)
{
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/HorizontalBinOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/HorizontalBinOpTest.template
deleted file mode 100644
index a3ae33c064..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/HorizontalBinOpTest.template
+++ /dev/null
@@ -1,418 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/******************************************************************************
- * This file is auto-generated from a template file by the GenerateTests.csx *
- * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
- * changes, please update the corresponding template and run according to the *
- * directions listed in the file. *
- ******************************************************************************/
-
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace JIT.HardwareIntrinsics.X86
-{
- public static partial class Program
- {
- private static void {Method}{RetBaseType}()
- {
- var test = new HorizontalBinaryOpTest__{Method}{RetBaseType}();
-
- if (test.IsSupported)
- {
- // Validates basic functionality works, using Unsafe.Read
- test.RunBasicScenario_UnsafeRead();
-
- if ({LoadIsa}.IsSupported)
- {
- // Validates basic functionality works, using Load
- test.RunBasicScenario_Load();
-
- // Validates basic functionality works, using LoadAligned
- test.RunBasicScenario_LoadAligned();
- }
-
- // Validates calling via reflection works, using Unsafe.Read
- test.RunReflectionScenario_UnsafeRead();
-
- if ({LoadIsa}.IsSupported)
- {
- // Validates calling via reflection works, using Load
- test.RunReflectionScenario_Load();
-
- // Validates calling via reflection works, using LoadAligned
- test.RunReflectionScenario_LoadAligned();
- }
-
- // Validates passing a static member works
- test.RunClsVarScenario();
-
- // Validates passing a local works, using Unsafe.Read
- test.RunLclVarScenario_UnsafeRead();
-
- if ({LoadIsa}.IsSupported)
- {
- // Validates passing a local works, using Load
- test.RunLclVarScenario_Load();
-
- // Validates passing a local works, using LoadAligned
- test.RunLclVarScenario_LoadAligned();
- }
-
- // Validates passing the field of a local class works
- test.RunClassLclFldScenario();
-
- // Validates passing an instance member of a class works
- test.RunClassFldScenario();
-
- // Validates passing the field of a local struct works
- test.RunStructLclFldScenario();
-
- // Validates passing an instance member of a struct works
- test.RunStructFldScenario();
- }
- else
- {
- // Validates we throw on unsupported hardware
- test.RunUnsupportedScenario();
- }
-
- if (!test.Succeeded)
- {
- throw new Exception("One or more scenarios did not complete as expected.");
- }
- }
- }
-
- public sealed unsafe class HorizontalBinaryOpTest__{Method}{RetBaseType}
- {
- private struct TestStruct
- {
- public {Op1VectorType}<{Op1BaseType}> _fld1;
- public {Op2VectorType}<{Op2BaseType}> _fld2;
-
- public static TestStruct Create()
- {
- var testStruct = new TestStruct();
-
- for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
-
- return testStruct;
- }
-
- public void RunStructFldScenario(HorizontalBinaryOpTest__{Method}{RetBaseType} testClass)
- {
- var result = {Isa}.{Method}(_fld1, _fld2);
-
- Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
- }
- }
-
- private static readonly int LargestVectorSize = {LargestVectorSize};
-
- private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType});
- private static readonly int Op2ElementCount = Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType});
- private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType});
-
- private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount];
- private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount];
-
- private static {Op1VectorType}<{Op1BaseType}> _clsVar1;
- private static {Op2VectorType}<{Op2BaseType}> _clsVar2;
-
- private {Op1VectorType}<{Op1BaseType}> _fld1;
- private {Op2VectorType}<{Op2BaseType}> _fld2;
-
- private HorizontalBinaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}> _dataTable;
-
- static HorizontalBinaryOpTest__{Method}{RetBaseType}()
- {
- for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _clsVar2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
- }
-
- public HorizontalBinaryOpTest__{Method}{RetBaseType}()
- {
- Succeeded = true;
-
- for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
-
- for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- _dataTable = new HorizontalBinaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}>(_data1, _data2, new {RetBaseType}[RetElementCount], LargestVectorSize);
- }
-
- public bool IsSupported => {Isa}.IsSupported;
-
- public bool Succeeded { get; set; }
-
- public void RunBasicScenario_UnsafeRead()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
-
- var result = {Isa}.{Method}(
- Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr),
- Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr)
- );
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
- }
-
- public void RunBasicScenario_Load()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
-
- var result = {Isa}.{Method}(
- {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr))
- );
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
- }
-
- public void RunBasicScenario_LoadAligned()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
-
- var result = {Isa}.{Method}(
- {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr))
- );
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
- }
-
- public void RunReflectionScenario_UnsafeRead()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
-
- var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>) })
- .Invoke(null, new object[] {
- Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr),
- Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr)
- });
-
- Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
- }
-
- public void RunReflectionScenario_Load()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
-
- var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>) })
- .Invoke(null, new object[] {
- {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr))
- });
-
- Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
- }
-
- public void RunReflectionScenario_LoadAligned()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
-
- var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>) })
- .Invoke(null, new object[] {
- {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr))
- });
-
- Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
- }
-
- public void RunClsVarScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
-
- var result = {Isa}.{Method}(
- _clsVar1,
- _clsVar2
- );
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
- }
-
- public void RunLclVarScenario_UnsafeRead()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
-
- var left = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr);
- var result = {Isa}.{Method}(left, right);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
- }
-
- public void RunLclVarScenario_Load()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
-
- var left = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
- var right = {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
- var result = {Isa}.{Method}(left, right);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
- }
-
- public void RunLclVarScenario_LoadAligned()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
-
- var left = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
- var right = {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
- var result = {Isa}.{Method}(left, right);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
- }
-
- public void RunClassLclFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
-
- var test = new HorizontalBinaryOpTest__{Method}{RetBaseType}();
- var result = {Isa}.{Method}(test._fld1, test._fld2);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
- }
-
- public void RunClassFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
-
- var result = {Isa}.{Method}(_fld1, _fld2);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
- }
-
- public void RunStructLclFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
-
- var test = TestStruct.Create();
- var result = {Isa}.{Method}(test._fld1, test._fld2);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
- }
-
- public void RunStructFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
-
- var test = TestStruct.Create();
- test.RunStructFldScenario(this);
- }
-
- public void RunUnsupportedScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
-
- bool succeeded = false;
-
- try
- {
- RunBasicScenario_UnsafeRead();
- }
- catch (PlatformNotSupportedException)
- {
- succeeded = true;
- }
-
- if (!succeeded)
- {
- Succeeded = false;
- }
- }
-
- private void ValidateResult({Op1VectorType}<{Op1BaseType}> left, {Op2VectorType}<{Op2BaseType}> right, void* result, [CallerMemberName] string method = "")
- {
- {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
- {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
- {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
-
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), right);
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>());
-
- ValidateResult(inArray1, inArray2, outArray, method);
- }
-
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
- {
- {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
- {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
- {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
-
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>());
-
- ValidateResult(inArray1, inArray2, outArray, method);
- }
-
- private void ValidateResult({Op1BaseType}[] left, {Op2BaseType}[] right, {RetBaseType}[] result, [CallerMemberName] string method = "")
- {
- bool succeeded = true;
-
- for (var outer = 0; outer < (LargestVectorSize / 16); outer++)
- {
- for (var inner = 0; inner < (8 / sizeof({RetBaseType})); inner++)
- {
- var i1 = (outer * (16 / sizeof({RetBaseType}))) + inner;
- var i2 = i1 + (8 / sizeof({RetBaseType}));
- var i3 = (outer * (16 / sizeof({RetBaseType}))) + (inner * 2);
-
- if ({ValidateFirstResult})
- {
- succeeded = false;
- break;
- }
-
- if ({ValidateRemainingResults})
- {
- succeeded = false;
- break;
- }
- }
- }
-
- if (!succeeded)
- {
- TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
- TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
- TestLibrary.TestFramework.LogInformation(string.Empty);
-
- Succeeded = false;
- }
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/HorizontalBinOpTest_DataTable.cs b/tests/src/JIT/HardwareIntrinsics/X86/Shared/HorizontalBinOpTest_DataTable.cs
deleted file mode 100644
index e9b6123066..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/HorizontalBinOpTest_DataTable.cs
+++ /dev/null
@@ -1,69 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace JIT.HardwareIntrinsics.X86
-{
- public unsafe struct HorizontalBinaryOpTest__DataTable<TResult, TOp1, TOp2> : IDisposable
- where TResult : struct
- where TOp1 : struct
- where TOp2 : struct
- {
- private byte[] inArray1;
- private byte[] inArray2;
- private byte[] outArray;
-
- private GCHandle inHandle1;
- private GCHandle inHandle2;
- private GCHandle outHandle;
-
- private ulong alignment;
-
- public HorizontalBinaryOpTest__DataTable(TOp1[] inArray1, TOp2[] inArray2, TResult[] outArray, int alignment)
- {
- int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<TOp1>();
- int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<TOp2>();
- int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<TResult>();
- if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
- {
- throw new ArgumentException("Invalid value of alignment");
- }
-
- this.inArray1 = new byte[alignment * 2];
- this.inArray2 = new byte[alignment * 2];
- this.outArray = new byte[alignment * 2];
-
- this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
- this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
- this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
-
- this.alignment = (ulong)alignment;
-
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<TOp1, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<TOp2, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
- }
-
- public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
- public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
- public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
-
- public void Dispose()
- {
- inHandle1.Free();
- inHandle2.Free();
- outHandle.Free();
- }
-
- private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
- {
- return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/SimpleTernOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/SimpleTernOpTest.template
deleted file mode 100644
index f79da6d24e..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/SimpleTernOpTest.template
+++ /dev/null
@@ -1,439 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/******************************************************************************
- * This file is auto-generated from a template file by the GenerateTests.csx *
- * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
- * changes, please update the corresponding template and run according to the *
- * directions listed in the file. *
- ******************************************************************************/
-
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace JIT.HardwareIntrinsics.X86
-{
- public static partial class Program
- {
- private static void {Method}{RetBaseType}()
- {
- var test = new SimpleTernaryOpTest__{Method}{RetBaseType}();
-
- if (test.IsSupported)
- {
- // Validates basic functionality works, using Unsafe.Read
- test.RunBasicScenario_UnsafeRead();
-
- if ({LoadIsa}.IsSupported)
- {
- // Validates basic functionality works, using Load
- test.RunBasicScenario_Load();
-
- // Validates basic functionality works, using LoadAligned
- test.RunBasicScenario_LoadAligned();
- }
-
- // Validates calling via reflection works, using Unsafe.Read
- test.RunReflectionScenario_UnsafeRead();
-
- if ({LoadIsa}.IsSupported)
- {
- // Validates calling via reflection works, using Load
- test.RunReflectionScenario_Load();
-
- // Validates calling via reflection works, using LoadAligned
- test.RunReflectionScenario_LoadAligned();
- }
-
- // Validates passing a static member works
- test.RunClsVarScenario();
-
- // Validates passing a local works, using Unsafe.Read
- test.RunLclVarScenario_UnsafeRead();
-
- if ({LoadIsa}.IsSupported)
- {
- // Validates passing a local works, using Load
- test.RunLclVarScenario_Load();
-
- // Validates passing a local works, using LoadAligned
- test.RunLclVarScenario_LoadAligned();
- }
-
- // Validates passing the field of a local class works
- test.RunClassLclFldScenario();
-
- // Validates passing an instance member of a class works
- test.RunClassFldScenario();
-
- // Validates passing the field of a local struct works
- test.RunStructLclFldScenario();
-
- // Validates passing an instance member of a struct works
- test.RunStructFldScenario();
- }
- else
- {
- // Validates we throw on unsupported hardware
- test.RunUnsupportedScenario();
- }
-
- if (!test.Succeeded)
- {
- throw new Exception("One or more scenarios did not complete as expected.");
- }
- }
- }
-
- public sealed unsafe class SimpleTernaryOpTest__{Method}{RetBaseType}
- {
- private struct TestStruct
- {
- public {Op1VectorType}<{Op1BaseType}> _fld1;
- public {Op2VectorType}<{Op2BaseType}> _fld2;
- public {Op3VectorType}<{Op3BaseType}> _fld3;
-
- public static TestStruct Create()
- {
- var testStruct = new TestStruct();
-
- for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
- for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3VectorType}<{Op3BaseType}>, byte>(ref _clsVar3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>());
-
- return testStruct;
- }
-
- public void RunStructFldScenario(SimpleTernaryOpTest__{Method}{RetBaseType} testClass)
- {
- var result = {Isa}.{Method}(_fld1, _fld2, _fld3);
-
- Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
- }
- }
-
- private static readonly int LargestVectorSize = {LargestVectorSize};
-
- private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType});
- private static readonly int Op2ElementCount = Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType});
- private static readonly int Op3ElementCount = Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>() / sizeof({Op3BaseType});
- private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType});
-
- private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount];
- private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount];
- private static {Op3BaseType}[] _data3 = new {Op3BaseType}[Op3ElementCount];
-
- private static {Op1VectorType}<{Op1BaseType}> _clsVar1;
- private static {Op2VectorType}<{Op2BaseType}> _clsVar2;
- private static {Op3VectorType}<{Op3BaseType}> _clsVar3;
-
- private {Op1VectorType}<{Op1BaseType}> _fld1;
- private {Op2VectorType}<{Op2BaseType}> _fld2;
- private {Op3VectorType}<{Op3BaseType}> _fld3;
-
- private SimpleTernaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}, {Op3BaseType}> _dataTable;
-
- static SimpleTernaryOpTest__{Method}{RetBaseType}()
- {
- for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _clsVar2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
- for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3VectorType}<{Op3BaseType}>, byte>(ref _clsVar3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>());
- }
-
- public SimpleTernaryOpTest__{Method}{RetBaseType}()
- {
- Succeeded = true;
-
- for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
- for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3VectorType}<{Op3BaseType}>, byte>(ref _fld3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>());
-
- for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; }
- _dataTable = new SimpleTernaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}, {Op3BaseType}>(_data1, _data2, _data3, new {RetBaseType}[RetElementCount], LargestVectorSize);
- }
-
- public bool IsSupported => {Isa}.IsSupported;
-
- public bool Succeeded { get; set; }
-
- public void RunBasicScenario_UnsafeRead()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
-
- var result = {Isa}.{Method}(
- Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr),
- Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr),
- Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr)
- );
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
- }
-
- public void RunBasicScenario_Load()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
-
- var result = {Isa}.{Method}(
- {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)),
- {LoadIsa}.Load{Op3VectorType}(({Op3BaseType}*)(_dataTable.inArray3Ptr))
- );
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
- }
-
- public void RunBasicScenario_LoadAligned()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
-
- var result = {Isa}.{Method}(
- {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)),
- {LoadIsa}.LoadAligned{Op3VectorType}(({Op3BaseType}*)(_dataTable.inArray3Ptr))
- );
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
- }
-
- public void RunReflectionScenario_UnsafeRead()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
-
- var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>), typeof({Op3VectorType}<{Op3BaseType}>) })
- .Invoke(null, new object[] {
- Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr),
- Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr),
- Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr)
- });
-
- Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
- }
-
- public void RunReflectionScenario_Load()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
-
- var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>), typeof({Op3VectorType}<{Op3BaseType}>) })
- .Invoke(null, new object[] {
- {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)),
- {LoadIsa}.Load{Op3VectorType}(({Op3BaseType}*)(_dataTable.inArray3Ptr))
- });
-
- Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
- }
-
- public void RunReflectionScenario_LoadAligned()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
-
- var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>), typeof({Op3VectorType}<{Op3BaseType}>) })
- .Invoke(null, new object[] {
- {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr)),
- {LoadIsa}.LoadAligned{Op3VectorType}(({Op3BaseType}*)(_dataTable.inArray3Ptr))
- });
-
- Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.inArray3Ptr, _dataTable.outArrayPtr);
- }
-
- public void RunClsVarScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
-
- var result = {Isa}.{Method}(
- _clsVar1,
- _clsVar2,
- _clsVar3
- );
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
- }
-
- public void RunLclVarScenario_UnsafeRead()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
-
- var firstOp = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr);
- var result = {Isa}.{Method}(firstOp, secondOp, thirdOp);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
- }
-
- public void RunLclVarScenario_Load()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
-
- var firstOp = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
- var secondOp = {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
- var thirdOp = {LoadIsa}.Load{Op3VectorType}(({Op3BaseType}*)(_dataTable.inArray3Ptr));
- var result = {Isa}.{Method}(firstOp, secondOp, thirdOp);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
- }
-
- public void RunLclVarScenario_LoadAligned()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
-
- var firstOp = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
- var secondOp = {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
- var thirdOp = {LoadIsa}.LoadAligned{Op3VectorType}(({Op3BaseType}*)(_dataTable.inArray3Ptr));
- var result = {Isa}.{Method}(firstOp, secondOp, thirdOp);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
- }
-
- public void RunClassLclFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
-
- var test = new SimpleTernaryOpTest__{Method}{RetBaseType}();
- var result = {Isa}.{Method}(test._fld1, test._fld2, test._fld3);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
- }
-
- public void RunClassFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
-
- var result = {Isa}.{Method}(_fld1, _fld2, _fld3);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
- }
-
- public void RunStructLclFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
-
- var test = TestStruct.Create();
- var result = {Isa}.{Method}(test._fld1, test._fld2, test._fld3);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
- }
-
- public void RunStructFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
-
- var test = TestStruct.Create();
- test.RunStructFldScenario(this);
- }
-
- public void RunUnsupportedScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
-
- bool succeeded = false;
-
- try
- {
- RunBasicScenario_UnsafeRead();
- }
- catch (PlatformNotSupportedException)
- {
- succeeded = true;
- }
-
- if (!succeeded)
- {
- Succeeded = false;
- }
- }
-
- private void ValidateResult({Op1VectorType}<{Op1BaseType}> firstOp, {Op2VectorType}<{Op2BaseType}> secondOp, {Op3VectorType}<{Op3BaseType}> thirdOp, void* result, [CallerMemberName] string method = "")
- {
- {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
- {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
- {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op3ElementCount];
- {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
-
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray3[0]), thirdOp);
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>());
-
- ValidateResult(inArray1, inArray2, inArray3, outArray, method);
- }
-
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
- {
- {Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
- {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
- {Op3BaseType}[] inArray3 = new {Op3BaseType}[Op3ElementCount];
- {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
-
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>());
-
- ValidateResult(inArray1, inArray2, inArray3, outArray, method);
- }
-
- private void ValidateResult({Op1BaseType}[] firstOp, {Op2BaseType}[] secondOp, {Op3BaseType}[] thirdOp, {RetBaseType}[] result, [CallerMemberName] string method = "")
- {
- bool succeeded = true;
-
- if ({ValidateFirstResult})
- {
- succeeded = false;
- }
- else
- {
- for (var i = 1; i < RetElementCount; i++)
- {
- if ({ValidateRemainingResults})
- {
- succeeded = false;
- break;
- }
- }
- }
-
- if (!succeeded)
- {
- TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>, {Op3VectorType}<{Op3BaseType}>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
- TestLibrary.TestFramework.LogInformation(string.Empty);
-
- Succeeded = false;
- }
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/SimpleTernOpTest_DataTable.cs b/tests/src/JIT/HardwareIntrinsics/X86/Shared/SimpleTernOpTest_DataTable.cs
deleted file mode 100644
index dbc9ac1f90..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/SimpleTernOpTest_DataTable.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace JIT.HardwareIntrinsics.X86
-{
- public unsafe struct SimpleTernaryOpTest__DataTable<TResult, TOp1, TOp2, TOp3> : IDisposable
- where TResult : struct
- where TOp1 : struct
- where TOp2 : struct
- where TOp3 : struct
- {
- private byte[] inArray1;
- private byte[] inArray2;
- private byte[] inArray3;
- private byte[] outArray;
-
- private GCHandle inHandle1;
- private GCHandle inHandle2;
- private GCHandle inHandle3;
- private GCHandle outHandle;
-
- private ulong alignment;
-
- public SimpleTernaryOpTest__DataTable(TOp1[] inArray1, TOp2[] inArray2, TOp3[] inArray3, TResult[] outArray, int alignment)
- {
- int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<TOp1>();
- int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<TOp2>();
- int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<TOp3>();
- int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<TResult>();
- if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 ||
- (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
- {
- throw new ArgumentException("Invalid value of alignment");
- }
-
- this.inArray1 = new byte[alignment * 2];
- this.inArray2 = new byte[alignment * 2];
- this.inArray3 = new byte[alignment * 2];
- this.outArray = new byte[alignment * 2];
-
- this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
- this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
- this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
- this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
-
- this.alignment = (ulong)alignment;
-
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<TOp1, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<TOp2, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
- Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<TOp3, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
- }
-
- public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
- public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
- public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
- public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
-
- public void Dispose()
- {
- inHandle1.Free();
- inHandle2.Free();
- inHandle3.Free();
- outHandle.Free();
- }
-
- private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
- {
- return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/SimpleUnOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/SimpleUnOpTest.template
deleted file mode 100644
index 59442938b7..0000000000
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/SimpleUnOpTest.template
+++ /dev/null
@@ -1,385 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-// See the LICENSE file in the project root for more information.
-
-/******************************************************************************
- * This file is auto-generated from a template file by the GenerateTests.csx *
- * script in tests\src\JIT\HardwareIntrinsics\X86\Shared. In order to make *
- * changes, please update the corresponding template and run according to the *
- * directions listed in the file. *
- ******************************************************************************/
-
-using System;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using System.Runtime.Intrinsics;
-using System.Runtime.Intrinsics.X86;
-
-namespace JIT.HardwareIntrinsics.X86
-{
- public static partial class Program
- {
- private static void {Method}{RetBaseType}()
- {
- var test = new SimpleUnaryOpTest__{Method}{RetBaseType}();
-
- if (test.IsSupported)
- {
- // Validates basic functionality works, using Unsafe.Read
- test.RunBasicScenario_UnsafeRead();
-
- if ({LoadIsa}.IsSupported)
- {
- // Validates basic functionality works, using Load
- test.RunBasicScenario_Load();
-
- // Validates basic functionality works, using LoadAligned
- test.RunBasicScenario_LoadAligned();
- }
-
- // Validates calling via reflection works, using Unsafe.Read
- test.RunReflectionScenario_UnsafeRead();
-
- if ({LoadIsa}.IsSupported)
- {
- // Validates calling via reflection works, using Load
- test.RunReflectionScenario_Load();
-
- // Validates calling via reflection works, using LoadAligned
- test.RunReflectionScenario_LoadAligned();
- }
-
- // Validates passing a static member works
- test.RunClsVarScenario();
-
- // Validates passing a local works, using Unsafe.Read
- test.RunLclVarScenario_UnsafeRead();
-
- if ({LoadIsa}.IsSupported)
- {
- // Validates passing a local works, using Load
- test.RunLclVarScenario_Load();
-
- // Validates passing a local works, using LoadAligned
- test.RunLclVarScenario_LoadAligned();
- }
-
- // Validates passing the field of a local class works
- test.RunClassLclFldScenario();
-
- // Validates passing an instance member of a class works
- test.RunClassFldScenario();
-
- // Validates passing the field of a local struct works
- test.RunStructLclFldScenario();
-
- // Validates passing an instance member of a struct works
- test.RunStructFldScenario();
- }
- else
- {
- // Validates we throw on unsupported hardware
- test.RunUnsupportedScenario();
- }
-
- if (!test.Succeeded)
- {
- throw new Exception("One or more scenarios did not complete as expected.");
- }
- }
- }
-
- public sealed unsafe class SimpleUnaryOpTest__{Method}{RetBaseType}
- {
- private struct TestStruct
- {
- public {Op1VectorType}<{Op1BaseType}> _fld;
-
- public static TestStruct Create()
- {
- var testStruct = new TestStruct();
-
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
-
- return testStruct;
- }
-
- public void RunStructFldScenario(SimpleUnaryOpTest__{Method}{RetBaseType} testClass)
- {
- var result = {Isa}.{Method}(_fld);
-
- Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
- }
- }
-
- 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}[] _data = new {Op1BaseType}[Op1ElementCount];
-
- private static {Op1VectorType}<{Op1BaseType}> _clsVar;
-
- private {Op1VectorType}<{Op1BaseType}> _fld;
-
- private SimpleUnaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}> _dataTable;
-
- static SimpleUnaryOpTest__{Method}{RetBaseType}()
- {
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- }
-
- public SimpleUnaryOpTest__{Method}{RetBaseType}()
- {
- Succeeded = true;
-
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld), ref Unsafe.As<{Op1BaseType}, byte>(ref _data[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
-
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = {NextValueOp1}; }
- _dataTable = new SimpleUnaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}>(_data, new {RetBaseType}[RetElementCount], LargestVectorSize);
- }
-
- public bool IsSupported => {Isa}.IsSupported;
-
- public bool Succeeded { get; set; }
-
- public void RunBasicScenario_UnsafeRead()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
-
- var result = {Isa}.{Method}(
- Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr)
- );
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
- }
-
- public void RunBasicScenario_Load()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
-
- var result = {Isa}.{Method}(
- {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr))
- );
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
- }
-
- public void RunBasicScenario_LoadAligned()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
-
- var result = {Isa}.{Method}(
- {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr))
- );
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
- }
-
- public void RunReflectionScenario_UnsafeRead()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
-
- var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>) })
- .Invoke(null, new object[] {
- Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr)
- });
-
- Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
- }
-
- public void RunReflectionScenario_Load()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
-
- var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>) })
- .Invoke(null, new object[] {
- {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr))
- });
-
- Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
- }
-
- public void RunReflectionScenario_LoadAligned()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
-
- var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>) })
- .Invoke(null, new object[] {
- {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr))
- });
-
- Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
- }
-
- public void RunClsVarScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
-
- var result = {Isa}.{Method}(
- _clsVar
- );
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
- }
-
- public void RunLclVarScenario_UnsafeRead()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
-
- var firstOp = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArrayPtr);
- var result = {Isa}.{Method}(firstOp);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
- }
-
- public void RunLclVarScenario_Load()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
-
- var firstOp = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr));
- var result = {Isa}.{Method}(firstOp);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
- }
-
- public void RunLclVarScenario_LoadAligned()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
-
- var firstOp = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArrayPtr));
- var result = {Isa}.{Method}(firstOp);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
- }
-
- public void RunClassLclFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
-
- var test = new SimpleUnaryOpTest__{Method}{RetBaseType}();
- var result = {Isa}.{Method}(test._fld);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
- }
-
- public void RunClassFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
-
- var result = {Isa}.{Method}(_fld);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
- }
-
- public void RunStructLclFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
-
- var test = TestStruct.Create();
- var result = {Isa}.{Method}(test._fld);
-
- Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
- }
-
- public void RunStructFldScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
-
- var test = TestStruct.Create();
- test.RunStructFldScenario(this);
- }
-
- public void RunUnsupportedScenario()
- {
- TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
-
- bool succeeded = false;
-
- try
- {
- RunBasicScenario_UnsafeRead();
- }
- catch (PlatformNotSupportedException)
- {
- succeeded = true;
- }
-
- if (!succeeded)
- {
- Succeeded = false;
- }
- }
-
- private void ValidateResult({Op1VectorType}<{Op1BaseType}> firstOp, void* result, [CallerMemberName] string method = "")
- {
- {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount];
- {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
-
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray[0]), firstOp);
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>());
-
- ValidateResult(inArray, outArray, method);
- }
-
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
- {
- {Op1BaseType}[] inArray = new {Op1BaseType}[Op1ElementCount];
- {RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
-
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>());
-
- ValidateResult(inArray, outArray, method);
- }
-
- private void ValidateResult({Op1BaseType}[] firstOp, {RetBaseType}[] result, [CallerMemberName] string method = "")
- {
- bool succeeded = true;
-
- if ({ValidateFirstResult})
- {
- succeeded = false;
- }
- else
- {
- for (var i = 1; i < RetElementCount; i++)
- {
- if ({ValidateRemainingResults})
- {
- succeeded = false;
- break;
- }
- }
- }
-
- if (!succeeded)
- {
- TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
- TestLibrary.TestFramework.LogInformation(string.Empty);
-
- Succeeded = false;
- }
- }
- }
-}
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/SimpleBinOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/_BinaryOpTestTemplate.template
index bdd016432d..94e6f09982 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/SimpleBinOpTest.template
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/_BinaryOpTestTemplate.template
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void {Method}{RetBaseType}()
{
- var test = new SimpleBinaryOpTest__{Method}{RetBaseType}();
+ var test = new {TemplateName}BinaryOpTest__{Method}{RetBaseType}();
if (test.IsSupported)
{
@@ -119,8 +119,61 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class SimpleBinaryOpTest__{Method}{RetBaseType}
+ public sealed unsafe class {TemplateName}BinaryOpTest__{Method}{RetBaseType}
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable({Op1BaseType}[] inArray1, {Op2BaseType}[] inArray2, {RetBaseType}[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public {Op1VectorType}<{Op1BaseType}> _fld1;
@@ -138,7 +191,7 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(SimpleBinaryOpTest__{Method}{RetBaseType} testClass)
+ public void RunStructFldScenario({TemplateName}BinaryOpTest__{Method}{RetBaseType} testClass)
{
var result = {Isa}.{Method}(_fld1, _fld2);
@@ -146,7 +199,7 @@ namespace JIT.HardwareIntrinsics.X86
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
- public void RunStructFldScenario_Load(SimpleBinaryOpTest__{Method}{RetBaseType} testClass)
+ public void RunStructFldScenario_Load({TemplateName}BinaryOpTest__{Method}{RetBaseType} testClass)
{
fixed ({Op1VectorType}<{Op1BaseType}>* pFld1 = &_fld1)
fixed ({Op2VectorType}<{Op2BaseType}>* pFld2 = &_fld2)
@@ -177,9 +230,9 @@ namespace JIT.HardwareIntrinsics.X86
private {Op1VectorType}<{Op1BaseType}> _fld1;
private {Op2VectorType}<{Op2BaseType}> _fld2;
- private SimpleBinaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}> _dataTable;
+ private DataTable _dataTable;
- static SimpleBinaryOpTest__{Method}{RetBaseType}()
+ static {TemplateName}BinaryOpTest__{Method}{RetBaseType}()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
@@ -187,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _clsVar2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
}
- public SimpleBinaryOpTest__{Method}{RetBaseType}()
+ public {TemplateName}BinaryOpTest__{Method}{RetBaseType}()
{
Succeeded = true;
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- _dataTable = new SimpleBinaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}>(_data1, _data2, new {RetBaseType}[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new {RetBaseType}[RetElementCount], LargestVectorSize);
}
public bool IsSupported => {Isa}.IsSupported;
@@ -320,43 +373,43 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr);
- var result = {Isa}.{Method}(left, right);
+ var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr);
+ var result = {Isa}.{Method}(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
- var right = {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
- var result = {Isa}.{Method}(left, right);
+ var op1 = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
+ var op2 = {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
+ var result = {Isa}.{Method}(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
- var right = {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
- var result = {Isa}.{Method}(left, right);
+ var op1 = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
+ var op2 = {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
+ var result = {Isa}.{Method}(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new SimpleBinaryOpTest__{Method}{RetBaseType}();
+ var test = new {TemplateName}BinaryOpTest__{Method}{RetBaseType}();
var result = {Isa}.{Method}(test._fld1, test._fld2);
Unsafe.Write(_dataTable.outArrayPtr, result);
@@ -367,7 +420,7 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
- var test = new SimpleBinaryOpTest__{Method}{RetBaseType}();
+ var test = new {TemplateName}BinaryOpTest__{Method}{RetBaseType}();
fixed ({Op1VectorType}<{Op1BaseType}>* pFld1 = &test._fld1)
fixed ({Op2VectorType}<{Op2BaseType}>* pFld2 = &test._fld2)
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult({Op1VectorType}<{Op1BaseType}> left, {Op2VectorType}<{Op2BaseType}> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, void* result, [CallerMemberName] string method = "")
{
{Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
{Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
{RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
{Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
{Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
{RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>());
ValidateResult(inArray1, inArray2, outArray, method);
@@ -501,21 +554,7 @@ namespace JIT.HardwareIntrinsics.X86
{
bool succeeded = true;
- if ({ValidateFirstResult})
- {
- succeeded = false;
- }
- else
- {
- for (var i = 1; i < RetElementCount; i++)
- {
- if ({ValidateRemainingResults})
- {
- succeeded = false;
- break;
- }
- }
- }
+ {TemplateValidationLogic}
if (!succeeded)
{
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanCmpOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/_BooleanBinaryOpTestTemplate.template
index 424619c481..667c7acfef 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanCmpOpTest.template
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/_BooleanBinaryOpTestTemplate.template
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void {Method}{RetBaseType}()
{
- var test = new BooleanComparisonOpTest__{Method}{RetBaseType}();
+ var test = new {TemplateName}BinaryOpTest__{Method}{RetBaseType}();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__{Method}{RetBaseType}
+ public sealed unsafe class {TemplateName}BinaryOpTest__{Method}{RetBaseType}
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable({Op1BaseType}[] inArray1, {Op2BaseType}[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public {Op1VectorType}<{Op1BaseType}> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__{Method}{RetBaseType} testClass)
+ public void RunStructFldScenario({TemplateName}BinaryOpTest__{Method}{RetBaseType} testClass)
{
var result = {Isa}.{Method}(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load({TemplateName}BinaryOpTest__{Method}{RetBaseType} testClass)
+ {
+ fixed ({Op1VectorType}<{Op1BaseType}>* pFld1 = &_fld1)
+ fixed ({Op2VectorType}<{Op2BaseType}>* pFld2 = &_fld2)
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pFld1)),
+ {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = {LargestVectorSize};
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private {Op1VectorType}<{Op1BaseType}> _fld1;
private {Op2VectorType}<{Op2BaseType}> _fld2;
- private BooleanComparisonOpTest__DataTable<{Op1BaseType}, {Op2BaseType}> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__{Method}{RetBaseType}()
+ static {TemplateName}BinaryOpTest__{Method}{RetBaseType}()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _clsVar2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
}
- public BooleanComparisonOpTest__{Method}{RetBaseType}()
+ public {TemplateName}BinaryOpTest__{Method}{RetBaseType}()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- _dataTable = new BooleanComparisonOpTest__DataTable<{Op1BaseType}, {Op2BaseType}>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => {Isa}.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed ({Op1VectorType}<{Op1BaseType}>* pClsVar1 = &_clsVar1)
+ fixed ({Op2VectorType}<{Op2BaseType}>* pClsVar2 = &_clsVar2)
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pClsVar1)),
+ {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr);
- var result = {Isa}.{Method}(left, right);
+ var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr);
+ var result = {Isa}.{Method}(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
- var right = {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
- var result = {Isa}.{Method}(left, right);
+ var op1 = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
+ var op2 = {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
+ var result = {Isa}.{Method}(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
- var right = {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
- var result = {Isa}.{Method}(left, right);
+ var op1 = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
+ var op2 = {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
+ var result = {Isa}.{Method}(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__{Method}{RetBaseType}();
+ var test = new {TemplateName}BinaryOpTest__{Method}{RetBaseType}();
var result = {Isa}.{Method}(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new {TemplateName}BinaryOpTest__{Method}{RetBaseType}();
+
+ fixed ({Op1VectorType}<{Op1BaseType}>* pFld1 = &test._fld1)
+ fixed ({Op2VectorType}<{Op2BaseType}>* pFld2 = &test._fld2)
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pFld1)),
+ {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed ({Op1VectorType}<{Op1BaseType}>* pFld1 = &_fld1)
+ fixed ({Op2VectorType}<{Op2BaseType}>* pFld2 = &_fld2)
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pFld1)),
+ {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(&test._fld1)),
+ {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,40 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult({Op1VectorType}<{Op1BaseType}> left, {Op2VectorType}<{Op2BaseType}> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, bool result, [CallerMemberName] string method = "")
{
{Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
{Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
{Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
{Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult({Op1BaseType}[] left, {Op2BaseType}[] right, bool result, [CallerMemberName] string method = "")
{
- if ({ValidateFirstResult})
+ bool succeeded = true;
+
+ {TemplateValidationLogic}
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanTwoCmpOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/_BooleanUnaryOpTestTemplate.template
index 6930a4de33..1a01d03910 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/BooleanTwoCmpOpTest.template
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/_BooleanUnaryOpTestTemplate.template
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void {Method}{RetBaseType}()
{
- var test = new BooleanTwoComparisonOpTest__{Method}{RetBaseType}();
+ var test = new {TemplateName}UnaryOpTest__{Method}{RetBaseType}();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,12 +119,49 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__{Method}{RetBaseType}
+ public sealed unsafe class {TemplateName}UnaryOpTest__{Method}{RetBaseType}
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+
+ private GCHandle inHandle1;
+
+ private ulong alignment;
+
+ public DataTable({Op1BaseType}[] inArray1, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public {Op1VectorType}<{Op1BaseType}> _fld1;
- public {Op2VectorType}<{Op2BaseType}> _fld2;
public static TestStruct Create()
{
@@ -102,55 +169,56 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__{Method}{RetBaseType} testClass)
+ public void RunStructFldScenario({TemplateName}UnaryOpTest__{Method}{RetBaseType} testClass)
+ {
+ var result = {Isa}.{Method}(_fld1);
+ testClass.ValidateResult(_fld1, result);
+ }
+
+ public void RunStructFldScenario_Load({TemplateName}UnaryOpTest__{Method}{RetBaseType} testClass)
{
- var result = {Isa}.{Method}(_fld1, _fld2);
- testClass.ValidateResult(_fld1, _fld2, result);
+ fixed ({Op1VectorType}<{Op1BaseType}>* pFld1 = &_fld1)
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pFld1))
+ );
+
+ testClass.ValidateResult(_fld1, result);
+ }
}
}
private static readonly int LargestVectorSize = {LargestVectorSize};
private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType});
- private static readonly int Op2ElementCount = Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType});
private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount];
- private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount];
private static {Op1VectorType}<{Op1BaseType}> _clsVar1;
- private static {Op2VectorType}<{Op2BaseType}> _clsVar2;
private {Op1VectorType}<{Op1BaseType}> _fld1;
- private {Op2VectorType}<{Op2BaseType}> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<{Op1BaseType}, {Op2BaseType}> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__{Method}{RetBaseType}()
+ static {TemplateName}UnaryOpTest__{Method}{RetBaseType}()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _clsVar2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
}
- public BooleanTwoComparisonOpTest__{Method}{RetBaseType}()
+ public {TemplateName}UnaryOpTest__{Method}{RetBaseType}()
{
Succeeded = true;
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<{Op1BaseType}, {Op2BaseType}>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, LargestVectorSize);
}
public bool IsSupported => {Isa}.IsSupported;
@@ -162,11 +230,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = {Isa}.{Method}(
- Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr),
- Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr)
+ Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr)
);
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_Load()
@@ -174,11 +241,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = {Isa}.{Method}(
- {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr))
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_LoadAligned()
@@ -186,62 +252,46 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = {Isa}.{Method}(
- {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr))
+ {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunReflectionScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
- Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr),
- Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr)
+ var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>) })
+ .Invoke(null, new object[] {
+ Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
- {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr))
+ var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>) })
+ .Invoke(null, new object[] {
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
- {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr))
+ var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>) })
+ .Invoke(null, new object[] {
+ {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -249,63 +299,103 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = {Isa}.{Method}(
- _clsVar1,
- _clsVar2
+ _clsVar1
);
- ValidateResult(_clsVar1, _clsVar2, result);
+ ValidateResult(_clsVar1, result);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed ({Op1VectorType}<{Op1BaseType}>* pClsVar1 = &_clsVar1)
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pClsVar1))
+ );
+
+ ValidateResult(_clsVar1, result);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr);
- var result = {Isa}.{Method}(left, right);
+ var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr);
+ var result = {Isa}.{Method}(op1);
- ValidateResult(left, right, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
- var right = {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
- var result = {Isa}.{Method}(left, right);
+ var op1 = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
+ var result = {Isa}.{Method}(op1);
- ValidateResult(left, right, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
- var right = {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
- var result = {Isa}.{Method}(left, right);
+ var op1 = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
+ var result = {Isa}.{Method}(op1);
- ValidateResult(left, right, result);
+ ValidateResult(op1, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__{Method}{RetBaseType}();
- var result = {Isa}.{Method}(test._fld1, test._fld2);
+ var test = new {TemplateName}UnaryOpTest__{Method}{RetBaseType}();
+ var result = {Isa}.{Method}(test._fld1);
+
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new {TemplateName}UnaryOpTest__{Method}{RetBaseType}();
- ValidateResult(test._fld1, test._fld2, result);
+ fixed ({Op1VectorType}<{Op1BaseType}>* pFld1 = &test._fld1)
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pFld1))
+ );
+
+ ValidateResult(test._fld1, result);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = {Isa}.{Method}(_fld1, _fld2);
+ var result = {Isa}.{Method}(_fld1);
- ValidateResult(_fld1, _fld2, result);
+ ValidateResult(_fld1, result);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed ({Op1VectorType}<{Op1BaseType}>* pFld1 = &_fld1)
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pFld1))
+ );
+
+ ValidateResult(_fld1, result);
+ }
}
public void RunStructLclFldScenario()
@@ -313,8 +403,20 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = {Isa}.{Method}(test._fld1, test._fld2);
- ValidateResult(test._fld1, test._fld2, result);
+ var result = {Isa}.{Method}(test._fld1);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(&test._fld1))
+ );
+
+ ValidateResult(test._fld1, result);
}
public void RunStructFldScenario()
@@ -325,6 +427,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,50 +456,35 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult({Op1VectorType}<{Op1BaseType}> left, {Op2VectorType}<{Op2BaseType}> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, bool result, [CallerMemberName] string method = "")
{
{Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
- {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1);
- ValidateResult(inArray1, inArray2, result, method);
+ ValidateResult(inArray1, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, bool result, [CallerMemberName] string method = "")
{
{Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
- {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- ValidateResult(inArray1, inArray2, result, method);
+ ValidateResult(inArray1, result, method);
}
- private void ValidateResult({Op1BaseType}[] left, {Op2BaseType}[] right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult({Op1BaseType}[] value, bool result, [CallerMemberName] string method = "")
{
- var expectedResult1 = true;
-
- for (var i = 0; i < Op1ElementCount; i++)
- {
- expectedResult1 &= ({ValidateFirstResult});
- }
-
- var expectedResult2 = true;
+ bool succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++)
- {
- expectedResult2 &= ({ValidateRemainingResults});
- }
+ {TemplateValidationLogic}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ if (!succeeded)
{
- TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
- TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>): {method} failed:");
+ TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/AlternatingTernOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/_TernaryOpTestTemplate.template
index db80cc2aca..f11023a3e6 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/AlternatingTernOpTest.template
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/_TernaryOpTestTemplate.template
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void {Method}{RetBaseType}()
{
- var test = new AlternatingTernaryOpTest__{Method}{RetBaseType}();
+ var test = new {TemplateName}TernaryOpTest__{Method}{RetBaseType}();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,13 +119,74 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class AlternatingTernaryOpTest__{Method}{RetBaseType}
+ public sealed unsafe class {TemplateName}TernaryOpTest__{Method}{RetBaseType}
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable({Op1BaseType}[] inArray1, {Op2BaseType}[] inArray2, {Op3BaseType}[] inArray3, {RetBaseType}[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<{Op2BaseType}>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<{Op3BaseType}>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public {Op1VectorType}<{Op1BaseType}> _fld1;
public {Op2VectorType}<{Op2BaseType}> _fld2;
- public {Op3VectorType}<{Op3BaseType}> _fld3;
+ public {Op2VectorType}<{Op3BaseType}> _fld3;
public static TestStruct Create()
{
@@ -111,13 +202,30 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(AlternatingTernaryOpTest__{Method}{RetBaseType} testClass)
+ public void RunStructFldScenario({TemplateName}TernaryOpTest__{Method}{RetBaseType} testClass)
{
var result = {Isa}.{Method}(_fld1, _fld2, _fld3);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load({TemplateName}TernaryOpTest__{Method}{RetBaseType} testClass)
+ {
+ fixed ({Op1VectorType}<{Op1BaseType}>* pFld1 = &_fld1)
+ fixed ({Op2VectorType}<{Op2BaseType}>* pFld2 = &_fld2)
+ fixed ({Op3VectorType}<{Op3BaseType}>* pFld3 = &_fld3)
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pFld1)),
+ {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(pFld2)),
+ {LoadIsa}.Load{Op3VectorType}(({Op3BaseType}*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = {LargestVectorSize};
@@ -139,9 +247,9 @@ namespace JIT.HardwareIntrinsics.X86
private {Op2VectorType}<{Op2BaseType}> _fld2;
private {Op3VectorType}<{Op3BaseType}> _fld3;
- private AlternatingTernaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}, {Op3BaseType}> _dataTable;
+ private DataTable _dataTable;
- static AlternatingTernaryOpTest__{Method}{RetBaseType}()
+ static {TemplateName}TernaryOpTest__{Method}{RetBaseType}()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
@@ -151,7 +259,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3VectorType}<{Op3BaseType}>, byte>(ref _clsVar3), ref Unsafe.As<{Op3BaseType}, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>());
}
- public AlternatingTernaryOpTest__{Method}{RetBaseType}()
+ public {TemplateName}TernaryOpTest__{Method}{RetBaseType}()
{
Succeeded = true;
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = {NextValueOp3}; }
- _dataTable = new AlternatingTernaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}, {Op3BaseType}>(_data1, _data2, _data3, new {RetBaseType}[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new {RetBaseType}[RetElementCount], LargestVectorSize);
}
public bool IsSupported => {Isa}.IsSupported;
@@ -273,56 +381,96 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed ({Op1VectorType}<{Op1BaseType}>* pClsVar1 = &_clsVar1)
+ fixed ({Op2VectorType}<{Op2BaseType}>* pClsVar2 = &_clsVar2)
+ fixed ({Op3VectorType}<{Op3BaseType}>* pClsVar3 = &_clsVar3)
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pClsVar1)),
+ {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(pClsVar2)),
+ {LoadIsa}.Load{Op3VectorType}(({Op3BaseType}*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr);
- var result = {Isa}.{Method}(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<{Op3VectorType}<{Op3BaseType}>>(_dataTable.inArray3Ptr);
+ var result = {Isa}.{Method}(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
- var secondOp = {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
- var thirdOp = {LoadIsa}.Load{Op3VectorType}(({Op3BaseType}*)(_dataTable.inArray3Ptr));
- var result = {Isa}.{Method}(firstOp, secondOp, thirdOp);
+ var op1 = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
+ var op2 = {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
+ var op3 = {LoadIsa}.Load{Op3VectorType}(({Op3BaseType}*)(_dataTable.inArray3Ptr));
+ var result = {Isa}.{Method}(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
- var secondOp = {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
- var thirdOp = {LoadIsa}.LoadAligned{Op3VectorType}(({Op3BaseType}*)(_dataTable.inArray3Ptr));
- var result = {Isa}.{Method}(firstOp, secondOp, thirdOp);
+ var op1 = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
+ var op2 = {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
+ var op3 = {LoadIsa}.LoadAligned{Op3VectorType}(({Op3BaseType}*)(_dataTable.inArray3Ptr));
+ var result = {Isa}.{Method}(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new AlternatingTernaryOpTest__{Method}{RetBaseType}();
+ var test = new {TemplateName}TernaryOpTest__{Method}{RetBaseType}();
var result = {Isa}.{Method}(test._fld1, test._fld2, test._fld3);
Unsafe.Write(_dataTable.outArrayPtr, result);
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new {TemplateName}TernaryOpTest__{Method}{RetBaseType}();
+
+ fixed ({Op1VectorType}<{Op1BaseType}>* pFld1 = &test._fld1)
+ fixed ({Op2VectorType}<{Op2BaseType}>* pFld2 = &test._fld2)
+ fixed ({Op3VectorType}<{Op3BaseType}>* pFld3 = &test._fld3)
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pFld1)),
+ {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(pFld2)),
+ {LoadIsa}.Load{Op3VectorType}(({Op3BaseType}*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed ({Op1VectorType}<{Op1BaseType}>* pFld1 = &_fld1)
+ fixed ({Op2VectorType}<{Op2BaseType}>* pFld2 = &_fld2)
+ fixed ({Op3VectorType}<{Op3BaseType}>* pFld3 = &_fld3)
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pFld1)),
+ {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(pFld2)),
+ {LoadIsa}.Load{Op3VectorType}(({Op3BaseType}*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(&test._fld1)),
+ {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(&test._fld2)),
+ {LoadIsa}.Load{Op3VectorType}(({Op3BaseType}*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult({Op1VectorType}<{Op1BaseType}> firstOp, {Op2VectorType}<{Op2BaseType}> secondOp, {Op3VectorType}<{Op3BaseType}> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, {Op2VectorType}<{Op2BaseType}> op2, {Op3VectorType}<{Op3BaseType}> op3, void* result, [CallerMemberName] string method = "")
{
{Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
{Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
{Op3BaseType}[] inArray3 = new {Op3BaseType}[Op3ElementCount];
{RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
{Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
{Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
{Op3BaseType}[] inArray3 = new {Op3BaseType}[Op3ElementCount];
{RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op3BaseType}, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<{Op3VectorType}<{Op3BaseType}>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -407,28 +597,15 @@ namespace JIT.HardwareIntrinsics.X86
{
bool succeeded = true;
- for (var i = 0; i < RetElementCount; i += 2)
- {
- if ({ValidateFirstResult})
- {
- succeeded = false;
- break;
- }
-
- if ({ValidateRemainingResults})
- {
- succeeded = false;
- break;
- }
- }
+ {TemplateValidationLogic}
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>, {Op3VectorType}<{Op3BaseType}>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Shared/AlternatingBinOpTest.template b/tests/src/JIT/HardwareIntrinsics/X86/Shared/_UnaryOpTestTemplate.template
index d0a2c20183..27836de4ee 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Shared/AlternatingBinOpTest.template
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Shared/_UnaryOpTestTemplate.template
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void {Method}{RetBaseType}()
{
- var test = new AlternatingBinaryOpTest__{Method}{RetBaseType}();
+ var test = new {TemplateName}UnaryOpTest__{Method}{RetBaseType}();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if ({LoadIsa}.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,12 +119,56 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class AlternatingBinaryOpTest__{Method}{RetBaseType}
+ public sealed unsafe class {TemplateName}UnaryOpTest__{Method}{RetBaseType}
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable({Op1BaseType}[] inArray1, {RetBaseType}[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<{Op1BaseType}>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<{RetBaseType}>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public {Op1VectorType}<{Op1BaseType}> _fld1;
- public {Op2VectorType}<{Op2BaseType}> _fld2;
public static TestStruct Create()
{
@@ -102,58 +176,60 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref testStruct._fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref testStruct._fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
return testStruct;
}
- public void RunStructFldScenario(AlternatingBinaryOpTest__{Method}{RetBaseType} testClass)
+ public void RunStructFldScenario({TemplateName}UnaryOpTest__{Method}{RetBaseType} testClass)
{
- var result = {Isa}.{Method}(_fld1, _fld2);
+ var result = {Isa}.{Method}(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load({TemplateName}UnaryOpTest__{Method}{RetBaseType} testClass)
+ {
+ fixed ({Op1VectorType}<{Op1BaseType}>* pFld1 = &_fld1)
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
private static readonly int LargestVectorSize = {LargestVectorSize};
private static readonly int Op1ElementCount = Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>() / sizeof({Op1BaseType});
- private static readonly int Op2ElementCount = Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>() / sizeof({Op2BaseType});
private static readonly int RetElementCount = Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>() / sizeof({RetBaseType});
private static {Op1BaseType}[] _data1 = new {Op1BaseType}[Op1ElementCount];
- private static {Op2BaseType}[] _data2 = new {Op2BaseType}[Op2ElementCount];
private static {Op1VectorType}<{Op1BaseType}> _clsVar1;
- private static {Op2VectorType}<{Op2BaseType}> _clsVar2;
private {Op1VectorType}<{Op1BaseType}> _fld1;
- private {Op2VectorType}<{Op2BaseType}> _fld2;
- private AlternatingBinaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}> _dataTable;
+ private DataTable _dataTable;
- static AlternatingBinaryOpTest__{Method}{RetBaseType}()
+ static {TemplateName}UnaryOpTest__{Method}{RetBaseType}()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _clsVar1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _clsVar2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
}
- public AlternatingBinaryOpTest__{Method}{RetBaseType}()
+ public {TemplateName}UnaryOpTest__{Method}{RetBaseType}()
{
Succeeded = true;
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1VectorType}<{Op1BaseType}>, byte>(ref _fld1), ref Unsafe.As<{Op1BaseType}, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2VectorType}<{Op2BaseType}>, byte>(ref _fld2), ref Unsafe.As<{Op2BaseType}, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = {NextValueOp1}; }
- for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = {NextValueOp2}; }
- _dataTable = new AlternatingBinaryOpTest__DataTable<{RetBaseType}, {Op1BaseType}, {Op2BaseType}>(_data1, _data2, new {RetBaseType}[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, new {RetBaseType}[RetElementCount], LargestVectorSize);
}
public bool IsSupported => {Isa}.IsSupported;
@@ -165,12 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = {Isa}.{Method}(
- Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr),
- Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr)
+ Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -178,12 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = {Isa}.{Method}(
- {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr))
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -191,54 +265,50 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = {Isa}.{Method}(
- {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr))
+ {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>) })
+ var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>) })
.Invoke(null, new object[] {
- Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr),
- Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr)
+ Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>) })
+ var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>) })
.Invoke(null, new object[] {
- {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr))
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>), typeof({Op2VectorType}<{Op2BaseType}>) })
+ var result = typeof({Isa}).GetMethod(nameof({Isa}.{Method}), new Type[] { typeof({Op1VectorType}<{Op1BaseType}>) })
.Invoke(null, new object[] {
- {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr)),
- {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr))
+ {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, ({RetVectorType}<{RetBaseType}>)(result));
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -246,69 +316,112 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = {Isa}.{Method}(
- _clsVar1,
- _clsVar2
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed ({Op1VectorType}<{Op1BaseType}>* pClsVar1 = &_clsVar1)
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<{Op2VectorType}<{Op2BaseType}>>(_dataTable.inArray2Ptr);
- var result = {Isa}.{Method}(left, right);
+ var op1 = Unsafe.Read<{Op1VectorType}<{Op1BaseType}>>(_dataTable.inArray1Ptr);
+ var result = {Isa}.{Method}(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
- var right = {LoadIsa}.Load{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
- var result = {Isa}.{Method}(left, right);
+ var op1 = {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
+ var result = {Isa}.{Method}(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
- var right = {LoadIsa}.LoadAligned{Op2VectorType}(({Op2BaseType}*)(_dataTable.inArray2Ptr));
- var result = {Isa}.{Method}(left, right);
+ var op1 = {LoadIsa}.LoadAligned{Op1VectorType}(({Op1BaseType}*)(_dataTable.inArray1Ptr));
+ var result = {Isa}.{Method}(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new AlternatingBinaryOpTest__{Method}{RetBaseType}();
- var result = {Isa}.{Method}(test._fld1, test._fld2);
+ var test = new {TemplateName}UnaryOpTest__{Method}{RetBaseType}();
+ var result = {Isa}.{Method}(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new {TemplateName}UnaryOpTest__{Method}{RetBaseType}();
+
+ fixed ({Op1VectorType}<{Op1BaseType}>* pFld1 = &test._fld1)
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = {Isa}.{Method}(_fld1, _fld2);
+ var result = {Isa}.{Method}(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed ({Op1VectorType}<{Op1BaseType}>* pFld1 = &_fld1)
+ {
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -316,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = {Isa}.{Method}(test._fld1, test._fld2);
+ var result = {Isa}.{Method}(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = {Isa}.{Method}(
+ {LoadIsa}.Load{Op1VectorType}(({Op1BaseType}*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -330,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -351,56 +485,38 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult({Op1VectorType}<{Op1BaseType}> left, {Op2VectorType}<{Op2BaseType}> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult({Op1VectorType}<{Op1BaseType}> op1, void* result, [CallerMemberName] string method = "")
{
{Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
- {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
{RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>());
- ValidateResult(inArray1, inArray2, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
{Op1BaseType}[] inArray1 = new {Op1BaseType}[Op1ElementCount];
- {Op2BaseType}[] inArray2 = new {Op2BaseType}[Op2ElementCount];
{RetBaseType}[] outArray = new {RetBaseType}[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op2BaseType}, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<{Op2VectorType}<{Op2BaseType}>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<{Op1BaseType}, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<{Op1VectorType}<{Op1BaseType}>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<{RetBaseType}, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<{RetVectorType}<{RetBaseType}>>());
- ValidateResult(inArray1, inArray2, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult({Op1BaseType}[] left, {Op2BaseType}[] right, {RetBaseType}[] result, [CallerMemberName] string method = "")
+ private void ValidateResult({Op1BaseType}[] firstOp, {RetBaseType}[] result, [CallerMemberName] string method = "")
{
bool succeeded = true;
- for (var i = 0; i < RetElementCount; i += 2)
- {
- if ({ValidateFirstResult})
- {
- succeeded = false;
- break;
- }
-
- if ({ValidateRemainingResults})
- {
- succeeded = false;
- break;
- }
- }
+ {TemplateValidationLogic}
if (!succeeded)
{
- TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>, {Op2VectorType}<{Op2BaseType}>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
- TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
+ TestLibrary.TestFramework.LogInformation($"{nameof({Isa})}.{nameof({Isa}.{Method})}<{RetBaseType}>({Op1VectorType}<{Op1BaseType}>): {method} failed:");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Add.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Add.Single.cs
index 0e99f0d93e..b67392cb40 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Add.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Add.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.Add(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.Add(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.Add(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/AddScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/AddScalar.Single.cs
index 09868ccea0..ad0a2780b0 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/AddScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/AddScalar.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddScalarSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.AddScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.AddScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.AddScalar(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.AddScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.AddScalar(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.AddScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/And.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/And.Single.cs
index 8cebea8c32..fc7b9d86d7 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/And.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/And.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.And(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.And(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.And(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/AndNot.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/AndNot.Single.cs
index 9caab56d7e..cf66098997 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/AndNot.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/AndNot.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.AndNot(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.AndNot(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqual.Single.cs
index 27fbeacc33..fc92b7c78b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqual.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareEqual.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThan.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThan.Single.cs
index b50d05bb9c..7a097424cc 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThan.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThan.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareGreaterThanSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareGreaterThan(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareGreaterThan(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqual.Single.cs
index 6fadf7df2a..326c701ec6 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqual.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareGreaterThanOrEqual.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanOrEqualSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareGreaterThanOrEqualSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareGreaterThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareGreaterThanOrEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareGreaterThanOrEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThan.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThan.Single.cs
index 7b5fc6eeaf..a8b4e34fd4 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThan.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThan.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareLessThanSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareLessThanSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareLessThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareLessThan(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareLessThan(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqual.Single.cs
index 379952eec3..91b5e3d018 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqual.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareLessThanOrEqual.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareLessThanOrEqualSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareLessThanOrEqualSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareLessThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareLessThanOrEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareLessThanOrEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqual.Single.cs
index 511b7b2ea9..404e3bb0fe 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqual.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotEqual.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareNotEqualSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareNotEqualSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareNotEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareNotEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareNotEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareNotEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareNotEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareNotEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThan.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThan.Single.cs
index 4584cceedf..c634815f1d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThan.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThan.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareNotGreaterThanSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareNotGreaterThanSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareNotGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareNotGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareNotGreaterThan(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareNotGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareNotGreaterThan(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareNotGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqual.Single.cs
index 8bcf572689..9a8b8e121f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqual.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotGreaterThanOrEqual.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareNotGreaterThanOrEqualSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareNotGreaterThanOrEqualSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareNotGreaterThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareNotGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareNotGreaterThanOrEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareNotGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareNotGreaterThanOrEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareNotGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThan.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThan.Single.cs
index e32c98e9c0..5b6bacac1e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThan.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThan.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareNotLessThanSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareNotLessThanSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareNotLessThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareNotLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareNotLessThan(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareNotLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareNotLessThan(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareNotLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqual.Single.cs
index 7e1d80c55f..e901fe7494 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqual.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareNotLessThanOrEqual.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareNotLessThanOrEqualSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareNotLessThanOrEqualSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareNotLessThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareNotLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareNotLessThanOrEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareNotLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareNotLessThanOrEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareNotLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrdered.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrdered.Single.cs
index 96e32a347e..be2ff1a938 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrdered.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareOrdered.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareOrderedSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareOrderedSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareOrdered(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareOrdered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareOrdered(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareOrdered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareOrdered(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareOrdered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarEqual.Single.cs
index a6da8fbba2..725c9d4eb7 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarEqual.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarEqual.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarEqualSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarEqualSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarGreaterThan.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarGreaterThan.Single.cs
index d44cb8a30a..906daefd89 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarGreaterThan.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarGreaterThan.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarGreaterThanSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarGreaterThanSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarGreaterThan(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarGreaterThan(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarGreaterThanOrEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarGreaterThanOrEqual.Single.cs
index 8bda7cb662..8fde79b56a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarGreaterThanOrEqual.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarGreaterThanOrEqual.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarGreaterThanOrEqualSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarGreaterThanOrEqualSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarGreaterThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarGreaterThanOrEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarGreaterThanOrEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarLessThan.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarLessThan.Single.cs
index f85644d765..c06b4ded73 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarLessThan.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarLessThan.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarLessThanSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarLessThanSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarLessThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarLessThan(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarLessThan(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarLessThanOrEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarLessThanOrEqual.Single.cs
index a730fd3a7d..3c53acac1d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarLessThanOrEqual.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarLessThanOrEqual.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarLessThanOrEqualSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarLessThanOrEqualSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarLessThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarLessThanOrEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarLessThanOrEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotEqual.Single.cs
index 8c69b8072e..a461a96fea 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotEqual.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotEqual.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarNotEqualSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarNotEqualSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarNotEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarNotEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarNotEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarNotEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarNotEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarNotEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotGreaterThan.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotGreaterThan.Single.cs
index 4e6de13771..5f2723e87c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotGreaterThan.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotGreaterThan.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarNotGreaterThanSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarNotGreaterThanSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarNotGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarNotGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarNotGreaterThan(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarNotGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarNotGreaterThan(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarNotGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotGreaterThanOrEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotGreaterThanOrEqual.Single.cs
index 475c642325..edc38afc78 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotGreaterThanOrEqual.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotGreaterThanOrEqual.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarNotGreaterThanOrEqualSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarNotGreaterThanOrEqualSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarNotGreaterThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarNotGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarNotGreaterThanOrEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarNotGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarNotGreaterThanOrEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarNotGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotLessThan.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotLessThan.Single.cs
index 4b92ff189c..788f468bb9 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotLessThan.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotLessThan.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarNotLessThanSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarNotLessThanSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarNotLessThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarNotLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarNotLessThan(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarNotLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarNotLessThan(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarNotLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotLessThanOrEqual.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotLessThanOrEqual.Single.cs
index 71839f16f6..8b7bd678ae 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotLessThanOrEqual.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarNotLessThanOrEqual.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarNotLessThanOrEqualSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarNotLessThanOrEqualSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarNotLessThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarNotLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarNotLessThanOrEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarNotLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarNotLessThanOrEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarNotLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrdered.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrdered.Single.cs
index 6db1ad8495..91d4b7d84a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrdered.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrdered.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarOrderedSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarOrderedSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarOrdered(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarOrdered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarOrdered(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarOrdered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarOrdered(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarOrdered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedEqual.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedEqual.Boolean.cs
index 01ef9f2dae..3d4e3884df 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedEqual.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedEqual.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarOrderedEqualBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarOrderedEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedEqualBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarOrderedEqualBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarOrderedEqualBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarOrderedEqualBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarOrderedEqualBoolean testClass)
{
var result = Sse.CompareScalarOrderedEqual(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarOrderedEqualBoolean testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarOrderedEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private BooleanComparisonOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarOrderedEqualBoolean()
+ static BooleanBinaryOpTest__CompareScalarOrderedEqualBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
- public BooleanComparisonOpTest__CompareScalarOrderedEqualBoolean()
+ public BooleanBinaryOpTest__CompareScalarOrderedEqualBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Single, Single>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse.CompareScalarOrderedEqual(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarOrderedEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarOrderedEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarOrderedEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarOrderedEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarOrderedEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarOrderedEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarOrderedEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedEqualBoolean();
var result = Sse.CompareScalarOrderedEqual(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedEqualBoolean();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ {
+ var result = Sse.CompareScalarOrderedEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarOrderedEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse.CompareScalarOrderedEqual(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] == right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse)}.{nameof(Sse.CompareScalarOrderedEqual)}<Boolean>(Vector128<Single>, Vector128<Single>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedGreaterThan.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedGreaterThan.Boolean.cs
index 4b2b1a3b05..34804fad30 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedGreaterThan.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedGreaterThan.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarOrderedGreaterThanBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarOrderedGreaterThanBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedGreaterThanBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarOrderedGreaterThanBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarOrderedGreaterThanBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarOrderedGreaterThanBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarOrderedGreaterThanBoolean testClass)
{
var result = Sse.CompareScalarOrderedGreaterThan(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarOrderedGreaterThanBoolean testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarOrderedGreaterThan(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private BooleanComparisonOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarOrderedGreaterThanBoolean()
+ static BooleanBinaryOpTest__CompareScalarOrderedGreaterThanBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
- public BooleanComparisonOpTest__CompareScalarOrderedGreaterThanBoolean()
+ public BooleanBinaryOpTest__CompareScalarOrderedGreaterThanBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Single, Single>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse.CompareScalarOrderedGreaterThan(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarOrderedGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarOrderedGreaterThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarOrderedGreaterThan(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarOrderedGreaterThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarOrderedGreaterThan(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarOrderedGreaterThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarOrderedGreaterThanBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedGreaterThanBoolean();
var result = Sse.CompareScalarOrderedGreaterThan(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedGreaterThanBoolean();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ {
+ var result = Sse.CompareScalarOrderedGreaterThan(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarOrderedGreaterThan(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse.CompareScalarOrderedGreaterThan(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] > right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse)}.{nameof(Sse.CompareScalarOrderedGreaterThan)}<Boolean>(Vector128<Single>, Vector128<Single>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedGreaterThanOrEqual.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedGreaterThanOrEqual.Boolean.cs
index 92b6e015df..ef180fb9ad 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedGreaterThanOrEqual.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedGreaterThanOrEqual.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarOrderedGreaterThanOrEqualBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean testClass)
{
var result = Sse.CompareScalarOrderedGreaterThanOrEqual(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarOrderedGreaterThanOrEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private BooleanComparisonOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean()
+ static BooleanBinaryOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
- public BooleanComparisonOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean()
+ public BooleanBinaryOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Single, Single>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse.CompareScalarOrderedGreaterThanOrEqual(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarOrderedGreaterThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarOrderedGreaterThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarOrderedGreaterThanOrEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarOrderedGreaterThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarOrderedGreaterThanOrEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarOrderedGreaterThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean();
var result = Sse.CompareScalarOrderedGreaterThanOrEqual(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ {
+ var result = Sse.CompareScalarOrderedGreaterThanOrEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarOrderedGreaterThanOrEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse.CompareScalarOrderedGreaterThanOrEqual(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] >= right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse)}.{nameof(Sse.CompareScalarOrderedGreaterThanOrEqual)}<Boolean>(Vector128<Single>, Vector128<Single>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedLessThan.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedLessThan.Boolean.cs
index 2724f73a73..5303302b7b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedLessThan.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedLessThan.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarOrderedLessThanBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarOrderedLessThanBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedLessThanBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarOrderedLessThanBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarOrderedLessThanBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarOrderedLessThanBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarOrderedLessThanBoolean testClass)
{
var result = Sse.CompareScalarOrderedLessThan(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarOrderedLessThanBoolean testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarOrderedLessThan(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private BooleanComparisonOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarOrderedLessThanBoolean()
+ static BooleanBinaryOpTest__CompareScalarOrderedLessThanBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
- public BooleanComparisonOpTest__CompareScalarOrderedLessThanBoolean()
+ public BooleanBinaryOpTest__CompareScalarOrderedLessThanBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Single, Single>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse.CompareScalarOrderedLessThan(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarOrderedLessThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarOrderedLessThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarOrderedLessThan(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarOrderedLessThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarOrderedLessThan(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarOrderedLessThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarOrderedLessThanBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedLessThanBoolean();
var result = Sse.CompareScalarOrderedLessThan(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedLessThanBoolean();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ {
+ var result = Sse.CompareScalarOrderedLessThan(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarOrderedLessThan(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse.CompareScalarOrderedLessThan(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] < right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse)}.{nameof(Sse.CompareScalarOrderedLessThan)}<Boolean>(Vector128<Single>, Vector128<Single>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedLessThanOrEqual.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedLessThanOrEqual.Boolean.cs
index 00baaff038..5346039ee4 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedLessThanOrEqual.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedLessThanOrEqual.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarOrderedLessThanOrEqualBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarOrderedLessThanOrEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedLessThanOrEqualBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarOrderedLessThanOrEqualBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarOrderedLessThanOrEqualBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarOrderedLessThanOrEqualBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarOrderedLessThanOrEqualBoolean testClass)
{
var result = Sse.CompareScalarOrderedLessThanOrEqual(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarOrderedLessThanOrEqualBoolean testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarOrderedLessThanOrEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private BooleanComparisonOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarOrderedLessThanOrEqualBoolean()
+ static BooleanBinaryOpTest__CompareScalarOrderedLessThanOrEqualBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
- public BooleanComparisonOpTest__CompareScalarOrderedLessThanOrEqualBoolean()
+ public BooleanBinaryOpTest__CompareScalarOrderedLessThanOrEqualBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Single, Single>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse.CompareScalarOrderedLessThanOrEqual(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarOrderedLessThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarOrderedLessThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarOrderedLessThanOrEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarOrderedLessThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarOrderedLessThanOrEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarOrderedLessThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarOrderedLessThanOrEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedLessThanOrEqualBoolean();
var result = Sse.CompareScalarOrderedLessThanOrEqual(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedLessThanOrEqualBoolean();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ {
+ var result = Sse.CompareScalarOrderedLessThanOrEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarOrderedLessThanOrEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse.CompareScalarOrderedLessThanOrEqual(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] <= right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse)}.{nameof(Sse.CompareScalarOrderedLessThanOrEqual)}<Boolean>(Vector128<Single>, Vector128<Single>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedNotEqual.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedNotEqual.Boolean.cs
index e9c7bd8421..795e875baa 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedNotEqual.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarOrderedNotEqual.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarOrderedNotEqualBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarOrderedNotEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedNotEqualBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarOrderedNotEqualBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarOrderedNotEqualBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarOrderedNotEqualBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarOrderedNotEqualBoolean testClass)
{
var result = Sse.CompareScalarOrderedNotEqual(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarOrderedNotEqualBoolean testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarOrderedNotEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private BooleanComparisonOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarOrderedNotEqualBoolean()
+ static BooleanBinaryOpTest__CompareScalarOrderedNotEqualBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
- public BooleanComparisonOpTest__CompareScalarOrderedNotEqualBoolean()
+ public BooleanBinaryOpTest__CompareScalarOrderedNotEqualBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Single, Single>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse.CompareScalarOrderedNotEqual(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarOrderedNotEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarOrderedNotEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarOrderedNotEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarOrderedNotEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarOrderedNotEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarOrderedNotEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarOrderedNotEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedNotEqualBoolean();
var result = Sse.CompareScalarOrderedNotEqual(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedNotEqualBoolean();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ {
+ var result = Sse.CompareScalarOrderedNotEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarOrderedNotEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse.CompareScalarOrderedNotEqual(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] != right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse)}.{nameof(Sse.CompareScalarOrderedNotEqual)}<Boolean>(Vector128<Single>, Vector128<Single>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnordered.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnordered.Single.cs
index 4f51678d42..323ee0c6ea 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnordered.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnordered.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarUnorderedSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarUnorderedSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarUnordered(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarUnordered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarUnordered(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarUnordered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarUnordered(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarUnordered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedEqual.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedEqual.Boolean.cs
index d33a057fda..d69b339bd4 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedEqual.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedEqual.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarUnorderedEqualBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedEqualBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarUnorderedEqualBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarUnorderedEqualBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarUnorderedEqualBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarUnorderedEqualBoolean testClass)
{
var result = Sse.CompareScalarUnorderedEqual(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarUnorderedEqualBoolean testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarUnorderedEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private BooleanComparisonOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarUnorderedEqualBoolean()
+ static BooleanBinaryOpTest__CompareScalarUnorderedEqualBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
- public BooleanComparisonOpTest__CompareScalarUnorderedEqualBoolean()
+ public BooleanBinaryOpTest__CompareScalarUnorderedEqualBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Single, Single>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse.CompareScalarUnorderedEqual(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarUnorderedEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarUnorderedEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarUnorderedEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarUnorderedEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarUnorderedEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarUnorderedEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedEqualBoolean();
var result = Sse.CompareScalarUnorderedEqual(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedEqualBoolean();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ {
+ var result = Sse.CompareScalarUnorderedEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarUnorderedEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse.CompareScalarUnorderedEqual(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] == right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse)}.{nameof(Sse.CompareScalarUnorderedEqual)}<Boolean>(Vector128<Single>, Vector128<Single>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedGreaterThan.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedGreaterThan.Boolean.cs
index 8ee255685c..bb610817b0 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedGreaterThan.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedGreaterThan.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarUnorderedGreaterThanBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanBoolean testClass)
{
var result = Sse.CompareScalarUnorderedGreaterThan(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanBoolean testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarUnorderedGreaterThan(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private BooleanComparisonOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanBoolean()
+ static BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
- public BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanBoolean()
+ public BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Single, Single>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse.CompareScalarUnorderedGreaterThan(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarUnorderedGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarUnorderedGreaterThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarUnorderedGreaterThan(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarUnorderedGreaterThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarUnorderedGreaterThan(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarUnorderedGreaterThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanBoolean();
var result = Sse.CompareScalarUnorderedGreaterThan(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanBoolean();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ {
+ var result = Sse.CompareScalarUnorderedGreaterThan(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarUnorderedGreaterThan(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse.CompareScalarUnorderedGreaterThan(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] > right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse)}.{nameof(Sse.CompareScalarUnorderedGreaterThan)}<Boolean>(Vector128<Single>, Vector128<Single>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedGreaterThanOrEqual.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedGreaterThanOrEqual.Boolean.cs
index 3ffcc3c24b..aca96b5f19 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedGreaterThanOrEqual.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedGreaterThanOrEqual.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarUnorderedGreaterThanOrEqualBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean testClass)
{
var result = Sse.CompareScalarUnorderedGreaterThanOrEqual(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarUnorderedGreaterThanOrEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private BooleanComparisonOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean()
+ static BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
- public BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean()
+ public BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Single, Single>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse.CompareScalarUnorderedGreaterThanOrEqual(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarUnorderedGreaterThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarUnorderedGreaterThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarUnorderedGreaterThanOrEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarUnorderedGreaterThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarUnorderedGreaterThanOrEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarUnorderedGreaterThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean();
var result = Sse.CompareScalarUnorderedGreaterThanOrEqual(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ {
+ var result = Sse.CompareScalarUnorderedGreaterThanOrEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarUnorderedGreaterThanOrEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse.CompareScalarUnorderedGreaterThanOrEqual(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] >= right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse)}.{nameof(Sse.CompareScalarUnorderedGreaterThanOrEqual)}<Boolean>(Vector128<Single>, Vector128<Single>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedLessThan.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedLessThan.Boolean.cs
index e6436ba69e..3c3210bd58 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedLessThan.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedLessThan.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarUnorderedLessThanBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedLessThanBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedLessThanBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarUnorderedLessThanBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarUnorderedLessThanBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarUnorderedLessThanBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarUnorderedLessThanBoolean testClass)
{
var result = Sse.CompareScalarUnorderedLessThan(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarUnorderedLessThanBoolean testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarUnorderedLessThan(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private BooleanComparisonOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarUnorderedLessThanBoolean()
+ static BooleanBinaryOpTest__CompareScalarUnorderedLessThanBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
- public BooleanComparisonOpTest__CompareScalarUnorderedLessThanBoolean()
+ public BooleanBinaryOpTest__CompareScalarUnorderedLessThanBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Single, Single>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse.CompareScalarUnorderedLessThan(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarUnorderedLessThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarUnorderedLessThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarUnorderedLessThan(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarUnorderedLessThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarUnorderedLessThan(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarUnorderedLessThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedLessThanBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedLessThanBoolean();
var result = Sse.CompareScalarUnorderedLessThan(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedLessThanBoolean();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ {
+ var result = Sse.CompareScalarUnorderedLessThan(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarUnorderedLessThan(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse.CompareScalarUnorderedLessThan(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] < right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse)}.{nameof(Sse.CompareScalarUnorderedLessThan)}<Boolean>(Vector128<Single>, Vector128<Single>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedLessThanOrEqual.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedLessThanOrEqual.Boolean.cs
index d1c04c8680..59a4612215 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedLessThanOrEqual.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedLessThanOrEqual.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarUnorderedLessThanOrEqualBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedLessThanOrEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedLessThanOrEqualBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarUnorderedLessThanOrEqualBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarUnorderedLessThanOrEqualBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarUnorderedLessThanOrEqualBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarUnorderedLessThanOrEqualBoolean testClass)
{
var result = Sse.CompareScalarUnorderedLessThanOrEqual(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarUnorderedLessThanOrEqualBoolean testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarUnorderedLessThanOrEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private BooleanComparisonOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarUnorderedLessThanOrEqualBoolean()
+ static BooleanBinaryOpTest__CompareScalarUnorderedLessThanOrEqualBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
- public BooleanComparisonOpTest__CompareScalarUnorderedLessThanOrEqualBoolean()
+ public BooleanBinaryOpTest__CompareScalarUnorderedLessThanOrEqualBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Single, Single>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse.CompareScalarUnorderedLessThanOrEqual(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarUnorderedLessThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarUnorderedLessThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarUnorderedLessThanOrEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarUnorderedLessThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarUnorderedLessThanOrEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarUnorderedLessThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedLessThanOrEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedLessThanOrEqualBoolean();
var result = Sse.CompareScalarUnorderedLessThanOrEqual(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedLessThanOrEqualBoolean();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ {
+ var result = Sse.CompareScalarUnorderedLessThanOrEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarUnorderedLessThanOrEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse.CompareScalarUnorderedLessThanOrEqual(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] <= right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse)}.{nameof(Sse.CompareScalarUnorderedLessThanOrEqual)}<Boolean>(Vector128<Single>, Vector128<Single>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedNotEqual.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedNotEqual.Boolean.cs
index 528ca5cb1a..2b0cd76cfa 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedNotEqual.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareScalarUnorderedNotEqual.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarUnorderedNotEqualBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedNotEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedNotEqualBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarUnorderedNotEqualBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarUnorderedNotEqualBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarUnorderedNotEqualBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarUnorderedNotEqualBoolean testClass)
{
var result = Sse.CompareScalarUnorderedNotEqual(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarUnorderedNotEqualBoolean testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarUnorderedNotEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private BooleanComparisonOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarUnorderedNotEqualBoolean()
+ static BooleanBinaryOpTest__CompareScalarUnorderedNotEqualBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
- public BooleanComparisonOpTest__CompareScalarUnorderedNotEqualBoolean()
+ public BooleanBinaryOpTest__CompareScalarUnorderedNotEqualBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Single, Single>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse.CompareScalarUnorderedNotEqual(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareScalarUnorderedNotEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareScalarUnorderedNotEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarUnorderedNotEqual(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarUnorderedNotEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareScalarUnorderedNotEqual(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareScalarUnorderedNotEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedNotEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedNotEqualBoolean();
var result = Sse.CompareScalarUnorderedNotEqual(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedNotEqualBoolean();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ {
+ var result = Sse.CompareScalarUnorderedNotEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse.CompareScalarUnorderedNotEqual(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse.CompareScalarUnorderedNotEqual(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Single[] left, Single[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] != right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse)}.{nameof(Sse.CompareScalarUnorderedNotEqual)}<Boolean>(Vector128<Single>, Vector128<Single>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnordered.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnordered.Single.cs
index e822fa1115..c6430e0fc8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnordered.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/CompareUnordered.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareUnorderedSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareUnorderedSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.CompareUnordered(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.CompareUnordered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareUnordered(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareUnordered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.CompareUnordered(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.CompareUnordered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Divide.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Divide.Single.cs
index b311f73ac9..f39ff7fc6f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Divide.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Divide.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__DivideSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__DivideSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.Divide(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.Divide(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.Divide(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.Divide(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.Divide(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.Divide(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/DivideScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/DivideScalar.Single.cs
index 398c7e2b80..db5f7e3f35 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/DivideScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/DivideScalar.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__DivideScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__DivideScalarSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.DivideScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.DivideScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.DivideScalar(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.DivideScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.DivideScalar(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.DivideScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Max.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Max.Single.cs
index df257c0d5d..ffa3793494 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Max.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Max.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.Max(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.Max(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.Max(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MaxScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/MaxScalar.Single.cs
index d27e634b90..936dd7c39f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MaxScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/MaxScalar.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxScalarSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.MaxScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.MaxScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.MaxScalar(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.MaxScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.MaxScalar(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.MaxScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Min.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Min.Single.cs
index 07991c192a..5fc0bc0d8f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Min.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Min.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.Min(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.Min(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.Min(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MinScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/MinScalar.Single.cs
index f3ebca03b3..56eb78ddb5 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MinScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/MinScalar.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinScalarSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.MinScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.MinScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.MinScalar(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.MinScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.MinScalar(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.MinScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Multiply.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Multiply.Single.cs
index 6b94478fe1..43af71dbad 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Multiply.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Multiply.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplySingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplySingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.Multiply(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.Multiply(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.Multiply(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.Multiply(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.Multiply(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.Multiply(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MultiplyScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/MultiplyScalar.Single.cs
index 983bce4b32..09e2d0c5b2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/MultiplyScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/MultiplyScalar.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyScalarSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.MultiplyScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.MultiplyScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.MultiplyScalar(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.MultiplyScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.MultiplyScalar(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.MultiplyScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Or.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Or.Single.cs
index 3c6f96bf8c..bc2975cc1d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Or.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Or.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.Or(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.Or(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.Or(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_r.csproj
index 9d6211cff2..8b00693063 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_r.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_r.csproj
@@ -83,11 +83,9 @@
<Compile Include="SubtractScalar.Single.cs" />
<Compile Include="Xor.Single.cs" />
<Compile Include="Program.Sse.cs" />
- <Compile Include="..\Shared\BooleanCmpOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleBinOpConvTest_DataTable.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleBinOpConvTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_ro.csproj
index ac42657960..283a4e49bd 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Sse_ro.csproj
@@ -83,11 +83,9 @@
<Compile Include="SubtractScalar.Single.cs" />
<Compile Include="Xor.Single.cs" />
<Compile Include="Program.Sse.cs" />
- <Compile Include="..\Shared\BooleanCmpOpTest_DataTable.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleBinOpConvTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Subtract.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Subtract.Single.cs
index c28b16949e..bab99ae418 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Subtract.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Subtract.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.Subtract(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.Subtract(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/SubtractScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/SubtractScalar.Single.cs
index 6bd9425ba9..855f975b6d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/SubtractScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/SubtractScalar.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractScalarSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.SubtractScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.SubtractScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.SubtractScalar(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.SubtractScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.SubtractScalar(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.SubtractScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Xor.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Xor.Single.cs
index ed29236fc6..5ff677dff0 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse/Xor.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse/Xor.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse.Xor(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.Xor(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse.Xor(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Byte.cs
index 2c968c3618..eed2857b38 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse2.Add(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Double.cs
index 7b3ef34c5b..bd115bd3b4 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.Add(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int16.cs
index 609077fa37..3b404f3534 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.Add(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int32.cs
index c62e3ebb6b..7c3b9fff29 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse2.Add(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int64.cs
index 5273f9fc0d..8fcea12d7b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int64> _fld1;
private Vector128<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var result = Sse2.Add(left, right);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, Vector128<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.SByte.cs
index 70d35ca609..dfd961c5e6 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse2.Add(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt16.cs
index 8ed78ae028..72691eea20 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse2.Add(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt32.cs
index 65eb29356b..2e38870668 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse2.Add(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt64.cs
index 087bc6ce25..a2a3712a0d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Add.UInt64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt64> _fld1;
private Vector128<UInt64> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddUInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
- var result = Sse2.Add(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse2.Add(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Add(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, Vector128<UInt64> op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Byte.cs
index 486d7805db..f15c938270 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddSaturateByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddSaturateByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse2.AddSaturate(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AddSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.AddSaturate(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.AddSaturate(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Int16.cs
index 8c25cc67fa..26b91d0622 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddSaturateInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddSaturateInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.AddSaturate(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AddSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.AddSaturate(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.AddSaturate(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.SByte.cs
index 7906396f46..d4c0f5489f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddSaturateSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddSaturateSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse2.AddSaturate(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AddSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.AddSaturate(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.AddSaturate(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.UInt16.cs
index 986520be38..16fcbf04d5 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddSaturate.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddSaturateUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddSaturateUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse2.AddSaturate(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AddSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.AddSaturate(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.AddSaturate(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar.Double.cs
index ef2fe726fb..cd5ad23058 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AddScalar.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AddScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AddScalarDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.AddScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AddScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.AddScalar(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.AddScalar(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AddScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Byte.cs
index 51c979213e..c48db07f91 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse2.And(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Double.cs
index 5ee4ef2de4..4937b85ef2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.And(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int16.cs
index e47475ec99..51d1f0037b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.And(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int32.cs
index 6c18d07415..7a9034786f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse2.And(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int64.cs
index 46284b20e5..9a718d562c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int64> _fld1;
private Vector128<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var result = Sse2.And(left, right);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, Vector128<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.SByte.cs
index aae99e13c5..497a146e32 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse2.And(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt16.cs
index 83e4df4825..4f9917d461 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse2.And(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt32.cs
index 02e791928a..54fea871e6 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse2.And(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt64.cs
index f03a2324df..3c4b2d754e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/And.UInt64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt64> _fld1;
private Vector128<UInt64> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndUInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
- var result = Sse2.And(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse2.And(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.And(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, Vector128<UInt64> op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Byte.cs
index 65bfe2c7ee..de0340059b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Double.cs
index 4ca274372c..f8d6ed7461 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int16.cs
index 7ff9d1a930..145cfcd7bd 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int32.cs
index f280e1bf3c..9360e4fd0a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int64.cs
index 5313848a6a..3c59829b52 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int64> _fld1;
private Vector128<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var result = Sse2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, Vector128<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.SByte.cs
index c25ec7d84d..d382900f82 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt16.cs
index 01ee6af6d3..df8db11a20 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt32.cs
index c90e62bf69..c05d840e36 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt64.cs
index 0722e38df7..12664b4841 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/AndNot.UInt64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AndNotUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt64> _fld1;
private Vector128<UInt64> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AndNotUInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
- var result = Sse2.AndNot(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse2.AndNot(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.AndNot(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, Vector128<UInt64> op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.Byte.cs
index 469cbd6833..204e404a40 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AverageByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AverageByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse2.Average(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Average(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Average(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Average(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Average(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Average(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.UInt16.cs
index ac29665cba..2c0246f2b2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Average.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__AverageUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__AverageUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse2.Average(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Average(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Average(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Average(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Average(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Average(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Byte.cs
index 8ca776053d..3bda3d4404 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Double.cs
index 7e0bbae813..fb629ffe72 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int16.cs
index 0a4a06730b..895e102a83 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int32.cs
index c902db87ee..346b0ece92 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.SByte.cs
index 5e7fb0600a..13db374b70 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt16.cs
index 242a0e4ba6..d76093d151 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt32.cs
index a10d84b70c..3dd04a1ca5 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareEqual.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Double.cs
index 2ba8c4cb6a..fb3098b291 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareGreaterThanDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareGreaterThan(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareGreaterThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int16.cs
index a88a0f8767..22fa8f72f0 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareGreaterThanInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareGreaterThan(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareGreaterThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int32.cs
index 3c85cba91f..7767f6bff9 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareGreaterThanInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareGreaterThan(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareGreaterThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.SByte.cs
index 943fd79a44..f3ab023693 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThan.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareGreaterThanSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareGreaterThan(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareGreaterThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual.Double.cs
index ff2a78c1bf..718ffdb45f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareGreaterThanOrEqual.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanOrEqualDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareGreaterThanOrEqualDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareGreaterThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareGreaterThanOrEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareGreaterThanOrEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Double.cs
index 961978ceae..1537db2e2e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareLessThanDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareLessThanDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareLessThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareLessThan(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareLessThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int16.cs
index ff9ecde1b1..33667baf43 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareLessThanInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareLessThanInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareLessThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareLessThan(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareLessThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int32.cs
index c4d1a76341..c2a9dc0497 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareLessThanInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareLessThanInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareLessThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareLessThan(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareLessThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.SByte.cs
index ba735e49d1..1d027578bc 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThan.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareLessThanSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareLessThanSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareLessThan(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareLessThan(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareLessThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual.Double.cs
index 9bb116c73b..b5a5f90f6a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareLessThanOrEqual.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareLessThanOrEqualDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareLessThanOrEqualDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareLessThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareLessThanOrEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareLessThanOrEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual.Double.cs
index 0f7d75915e..5f50ae9872 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotEqual.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareNotEqualDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareNotEqualDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareNotEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareNotEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareNotEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareNotEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan.Double.cs
index 2f6bf64e9c..6aec3f89be 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThan.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareNotGreaterThanDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareNotGreaterThanDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareNotGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareNotGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareNotGreaterThan(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareNotGreaterThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual.Double.cs
index 922f2bcca2..6833f5fb83 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotGreaterThanOrEqual.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareNotGreaterThanOrEqualDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareNotGreaterThanOrEqualDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareNotGreaterThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareNotGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareNotGreaterThanOrEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareNotGreaterThanOrEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan.Double.cs
index fd4eaf4873..1362a7c975 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThan.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareNotLessThanDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareNotLessThanDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareNotLessThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareNotLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareNotLessThan(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareNotLessThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual.Double.cs
index 648fb88dcc..183098f12d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareNotLessThanOrEqual.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareNotLessThanOrEqualDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareNotLessThanOrEqualDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareNotLessThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareNotLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareNotLessThanOrEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareNotLessThanOrEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareNotLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered.Double.cs
index 2c9839677d..21d35acce2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareOrdered.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareOrderedDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareOrderedDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareOrdered(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareOrdered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareOrdered(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareOrdered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareOrdered(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareOrdered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarEqual.Double.cs
index e829a7a645..306207b1aa 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarEqual.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarEqual.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarEqualDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarEqualDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarGreaterThan.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarGreaterThan.Double.cs
index b4af1fb8f8..357d8dcf5f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarGreaterThan.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarGreaterThan.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarGreaterThanDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarGreaterThanDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarGreaterThan(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarGreaterThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarGreaterThanOrEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarGreaterThanOrEqual.Double.cs
index 018dd27124..209549cbbf 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarGreaterThanOrEqual.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarGreaterThanOrEqual.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarGreaterThanOrEqualDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarGreaterThanOrEqualDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarGreaterThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarGreaterThanOrEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarGreaterThanOrEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarLessThan.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarLessThan.Double.cs
index 55105bac1c..cebe90c998 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarLessThan.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarLessThan.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarLessThanDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarLessThanDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarLessThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarLessThan(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarLessThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarLessThanOrEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarLessThanOrEqual.Double.cs
index 379c9157d7..eda09af8d5 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarLessThanOrEqual.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarLessThanOrEqual.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarLessThanOrEqualDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarLessThanOrEqualDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarLessThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarLessThanOrEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarLessThanOrEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotEqual.Double.cs
index e64966b12e..8a914aec07 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotEqual.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotEqual.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarNotEqualDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarNotEqualDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarNotEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarNotEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarNotEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarNotEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarNotEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarNotEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotGreaterThan.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotGreaterThan.Double.cs
index 6b2e0c0fa3..2a8a0b6a15 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotGreaterThan.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotGreaterThan.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarNotGreaterThanDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarNotGreaterThanDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarNotGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarNotGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarNotGreaterThan(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarNotGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarNotGreaterThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarNotGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotGreaterThanOrEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotGreaterThanOrEqual.Double.cs
index 6440a9e321..c5fd626071 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotGreaterThanOrEqual.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotGreaterThanOrEqual.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarNotGreaterThanOrEqualDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarNotGreaterThanOrEqualDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarNotGreaterThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarNotGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarNotGreaterThanOrEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarNotGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarNotGreaterThanOrEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarNotGreaterThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotLessThan.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotLessThan.Double.cs
index 58196238b9..f12ecfee3e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotLessThan.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotLessThan.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarNotLessThanDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarNotLessThanDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarNotLessThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarNotLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarNotLessThan(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarNotLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarNotLessThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarNotLessThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotLessThanOrEqual.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotLessThanOrEqual.Double.cs
index 90e0cc54a1..cebbbfb751 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotLessThanOrEqual.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarNotLessThanOrEqual.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarNotLessThanOrEqualDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarNotLessThanOrEqualDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarNotLessThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarNotLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarNotLessThanOrEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarNotLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarNotLessThanOrEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarNotLessThanOrEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrdered.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrdered.Double.cs
index 116c94bd28..23b5c4d959 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrdered.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrdered.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarOrderedDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarOrderedDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarOrdered(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarOrdered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarOrdered(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarOrdered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarOrdered(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarOrdered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedEqual.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedEqual.Boolean.cs
index 6281a9cfc5..daa0e222d7 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedEqual.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedEqual.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarOrderedEqualBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarOrderedEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedEqualBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarOrderedEqualBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarOrderedEqualBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarOrderedEqualBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarOrderedEqualBoolean testClass)
{
var result = Sse2.CompareScalarOrderedEqual(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarOrderedEqualBoolean testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarOrderedEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarOrderedEqualBoolean()
+ static BooleanBinaryOpTest__CompareScalarOrderedEqualBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
- public BooleanComparisonOpTest__CompareScalarOrderedEqualBoolean()
+ public BooleanBinaryOpTest__CompareScalarOrderedEqualBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse2.CompareScalarOrderedEqual(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarOrderedEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarOrderedEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarOrderedEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarOrderedEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarOrderedEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarOrderedEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarOrderedEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedEqualBoolean();
var result = Sse2.CompareScalarOrderedEqual(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedEqualBoolean();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ {
+ var result = Sse2.CompareScalarOrderedEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarOrderedEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse2.CompareScalarOrderedEqual(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] == right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareScalarOrderedEqual)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedGreaterThan.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedGreaterThan.Boolean.cs
index 182800c87f..f6352a35bb 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedGreaterThan.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedGreaterThan.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarOrderedGreaterThanBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarOrderedGreaterThanBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedGreaterThanBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarOrderedGreaterThanBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarOrderedGreaterThanBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarOrderedGreaterThanBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarOrderedGreaterThanBoolean testClass)
{
var result = Sse2.CompareScalarOrderedGreaterThan(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarOrderedGreaterThanBoolean testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarOrderedGreaterThan(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarOrderedGreaterThanBoolean()
+ static BooleanBinaryOpTest__CompareScalarOrderedGreaterThanBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
- public BooleanComparisonOpTest__CompareScalarOrderedGreaterThanBoolean()
+ public BooleanBinaryOpTest__CompareScalarOrderedGreaterThanBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse2.CompareScalarOrderedGreaterThan(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarOrderedGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarOrderedGreaterThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarOrderedGreaterThan(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarOrderedGreaterThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarOrderedGreaterThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarOrderedGreaterThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarOrderedGreaterThanBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedGreaterThanBoolean();
var result = Sse2.CompareScalarOrderedGreaterThan(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedGreaterThanBoolean();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ {
+ var result = Sse2.CompareScalarOrderedGreaterThan(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarOrderedGreaterThan(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse2.CompareScalarOrderedGreaterThan(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] > right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareScalarOrderedGreaterThan)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedGreaterThanOrEqual.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedGreaterThanOrEqual.Boolean.cs
index 0e5ce983f3..65122a4510 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedGreaterThanOrEqual.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedGreaterThanOrEqual.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarOrderedGreaterThanOrEqualBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean testClass)
{
var result = Sse2.CompareScalarOrderedGreaterThanOrEqual(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarOrderedGreaterThanOrEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean()
+ static BooleanBinaryOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
- public BooleanComparisonOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean()
+ public BooleanBinaryOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse2.CompareScalarOrderedGreaterThanOrEqual(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarOrderedGreaterThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarOrderedGreaterThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarOrderedGreaterThanOrEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarOrderedGreaterThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarOrderedGreaterThanOrEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarOrderedGreaterThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean();
var result = Sse2.CompareScalarOrderedGreaterThanOrEqual(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedGreaterThanOrEqualBoolean();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ {
+ var result = Sse2.CompareScalarOrderedGreaterThanOrEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarOrderedGreaterThanOrEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse2.CompareScalarOrderedGreaterThanOrEqual(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] >= right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareScalarOrderedGreaterThanOrEqual)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedLessThan.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedLessThan.Boolean.cs
index fcd5dd0090..552716621a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedLessThan.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedLessThan.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarOrderedLessThanBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarOrderedLessThanBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedLessThanBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarOrderedLessThanBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarOrderedLessThanBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarOrderedLessThanBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarOrderedLessThanBoolean testClass)
{
var result = Sse2.CompareScalarOrderedLessThan(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarOrderedLessThanBoolean testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarOrderedLessThan(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarOrderedLessThanBoolean()
+ static BooleanBinaryOpTest__CompareScalarOrderedLessThanBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
- public BooleanComparisonOpTest__CompareScalarOrderedLessThanBoolean()
+ public BooleanBinaryOpTest__CompareScalarOrderedLessThanBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse2.CompareScalarOrderedLessThan(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarOrderedLessThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarOrderedLessThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarOrderedLessThan(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarOrderedLessThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarOrderedLessThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarOrderedLessThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarOrderedLessThanBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedLessThanBoolean();
var result = Sse2.CompareScalarOrderedLessThan(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedLessThanBoolean();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ {
+ var result = Sse2.CompareScalarOrderedLessThan(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarOrderedLessThan(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse2.CompareScalarOrderedLessThan(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] < right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareScalarOrderedLessThan)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedLessThanOrEqual.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedLessThanOrEqual.Boolean.cs
index 01b41e293f..e0ee6f5ac9 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedLessThanOrEqual.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedLessThanOrEqual.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarOrderedLessThanOrEqualBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarOrderedLessThanOrEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedLessThanOrEqualBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarOrderedLessThanOrEqualBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarOrderedLessThanOrEqualBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarOrderedLessThanOrEqualBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarOrderedLessThanOrEqualBoolean testClass)
{
var result = Sse2.CompareScalarOrderedLessThanOrEqual(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarOrderedLessThanOrEqualBoolean testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarOrderedLessThanOrEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarOrderedLessThanOrEqualBoolean()
+ static BooleanBinaryOpTest__CompareScalarOrderedLessThanOrEqualBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
- public BooleanComparisonOpTest__CompareScalarOrderedLessThanOrEqualBoolean()
+ public BooleanBinaryOpTest__CompareScalarOrderedLessThanOrEqualBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse2.CompareScalarOrderedLessThanOrEqual(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarOrderedLessThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarOrderedLessThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarOrderedLessThanOrEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarOrderedLessThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarOrderedLessThanOrEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarOrderedLessThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarOrderedLessThanOrEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedLessThanOrEqualBoolean();
var result = Sse2.CompareScalarOrderedLessThanOrEqual(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedLessThanOrEqualBoolean();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ {
+ var result = Sse2.CompareScalarOrderedLessThanOrEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarOrderedLessThanOrEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse2.CompareScalarOrderedLessThanOrEqual(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] <= right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareScalarOrderedLessThanOrEqual)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedNotEqual.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedNotEqual.Boolean.cs
index 59aa6f2d0e..789f014efc 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedNotEqual.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarOrderedNotEqual.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarOrderedNotEqualBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarOrderedNotEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedNotEqualBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarOrderedNotEqualBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarOrderedNotEqualBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarOrderedNotEqualBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarOrderedNotEqualBoolean testClass)
{
var result = Sse2.CompareScalarOrderedNotEqual(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarOrderedNotEqualBoolean testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarOrderedNotEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarOrderedNotEqualBoolean()
+ static BooleanBinaryOpTest__CompareScalarOrderedNotEqualBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
- public BooleanComparisonOpTest__CompareScalarOrderedNotEqualBoolean()
+ public BooleanBinaryOpTest__CompareScalarOrderedNotEqualBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse2.CompareScalarOrderedNotEqual(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarOrderedNotEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarOrderedNotEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarOrderedNotEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarOrderedNotEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarOrderedNotEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarOrderedNotEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarOrderedNotEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedNotEqualBoolean();
var result = Sse2.CompareScalarOrderedNotEqual(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarOrderedNotEqualBoolean();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ {
+ var result = Sse2.CompareScalarOrderedNotEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarOrderedNotEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse2.CompareScalarOrderedNotEqual(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] != right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareScalarOrderedNotEqual)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnordered.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnordered.Double.cs
index 83d57c49ef..d9f30b63cb 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnordered.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnordered.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareScalarUnorderedDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareScalarUnorderedDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarUnordered(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarUnordered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarUnordered(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarUnordered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarUnordered(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarUnordered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedEqual.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedEqual.Boolean.cs
index 5ad4073edf..75d398d5dd 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedEqual.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedEqual.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarUnorderedEqualBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedEqualBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarUnorderedEqualBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarUnorderedEqualBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarUnorderedEqualBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarUnorderedEqualBoolean testClass)
{
var result = Sse2.CompareScalarUnorderedEqual(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarUnorderedEqualBoolean testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarUnorderedEqualBoolean()
+ static BooleanBinaryOpTest__CompareScalarUnorderedEqualBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
- public BooleanComparisonOpTest__CompareScalarUnorderedEqualBoolean()
+ public BooleanBinaryOpTest__CompareScalarUnorderedEqualBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse2.CompareScalarUnorderedEqual(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarUnorderedEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarUnorderedEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarUnorderedEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarUnorderedEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarUnorderedEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarUnorderedEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedEqualBoolean();
var result = Sse2.CompareScalarUnorderedEqual(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedEqualBoolean();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse2.CompareScalarUnorderedEqual(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] == right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareScalarUnorderedEqual)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedGreaterThan.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedGreaterThan.Boolean.cs
index 0ea2751f22..38dd15aabd 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedGreaterThan.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedGreaterThan.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarUnorderedGreaterThanBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanBoolean testClass)
{
var result = Sse2.CompareScalarUnorderedGreaterThan(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanBoolean testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedGreaterThan(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanBoolean()
+ static BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
- public BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanBoolean()
+ public BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse2.CompareScalarUnorderedGreaterThan(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarUnorderedGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarUnorderedGreaterThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarUnorderedGreaterThan(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarUnorderedGreaterThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarUnorderedGreaterThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarUnorderedGreaterThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanBoolean();
var result = Sse2.CompareScalarUnorderedGreaterThan(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanBoolean();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedGreaterThan(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedGreaterThan(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse2.CompareScalarUnorderedGreaterThan(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] > right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareScalarUnorderedGreaterThan)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedGreaterThanOrEqual.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedGreaterThanOrEqual.Boolean.cs
index 5f9483973b..4e1fde1fe3 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedGreaterThanOrEqual.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedGreaterThanOrEqual.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarUnorderedGreaterThanOrEqualBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean testClass)
{
var result = Sse2.CompareScalarUnorderedGreaterThanOrEqual(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedGreaterThanOrEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean()
+ static BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
- public BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean()
+ public BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse2.CompareScalarUnorderedGreaterThanOrEqual(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarUnorderedGreaterThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarUnorderedGreaterThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarUnorderedGreaterThanOrEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarUnorderedGreaterThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarUnorderedGreaterThanOrEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarUnorderedGreaterThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean();
var result = Sse2.CompareScalarUnorderedGreaterThanOrEqual(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedGreaterThanOrEqualBoolean();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedGreaterThanOrEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedGreaterThanOrEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse2.CompareScalarUnorderedGreaterThanOrEqual(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] >= right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareScalarUnorderedGreaterThanOrEqual)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedLessThan.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedLessThan.Boolean.cs
index 9544c8bcdf..dc649c836c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedLessThan.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedLessThan.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarUnorderedLessThanBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedLessThanBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedLessThanBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarUnorderedLessThanBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarUnorderedLessThanBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarUnorderedLessThanBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarUnorderedLessThanBoolean testClass)
{
var result = Sse2.CompareScalarUnorderedLessThan(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarUnorderedLessThanBoolean testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedLessThan(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarUnorderedLessThanBoolean()
+ static BooleanBinaryOpTest__CompareScalarUnorderedLessThanBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
- public BooleanComparisonOpTest__CompareScalarUnorderedLessThanBoolean()
+ public BooleanBinaryOpTest__CompareScalarUnorderedLessThanBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse2.CompareScalarUnorderedLessThan(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarUnorderedLessThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarUnorderedLessThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarUnorderedLessThan(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarUnorderedLessThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarUnorderedLessThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarUnorderedLessThan(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedLessThanBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedLessThanBoolean();
var result = Sse2.CompareScalarUnorderedLessThan(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedLessThanBoolean();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedLessThan(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedLessThan(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse2.CompareScalarUnorderedLessThan(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] < right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareScalarUnorderedLessThan)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedLessThanOrEqual.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedLessThanOrEqual.Boolean.cs
index e2f81dd693..eb107dfba0 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedLessThanOrEqual.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedLessThanOrEqual.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarUnorderedLessThanOrEqualBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedLessThanOrEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedLessThanOrEqualBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarUnorderedLessThanOrEqualBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarUnorderedLessThanOrEqualBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarUnorderedLessThanOrEqualBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarUnorderedLessThanOrEqualBoolean testClass)
{
var result = Sse2.CompareScalarUnorderedLessThanOrEqual(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarUnorderedLessThanOrEqualBoolean testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedLessThanOrEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarUnorderedLessThanOrEqualBoolean()
+ static BooleanBinaryOpTest__CompareScalarUnorderedLessThanOrEqualBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
- public BooleanComparisonOpTest__CompareScalarUnorderedLessThanOrEqualBoolean()
+ public BooleanBinaryOpTest__CompareScalarUnorderedLessThanOrEqualBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse2.CompareScalarUnorderedLessThanOrEqual(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarUnorderedLessThanOrEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarUnorderedLessThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarUnorderedLessThanOrEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarUnorderedLessThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarUnorderedLessThanOrEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarUnorderedLessThanOrEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedLessThanOrEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedLessThanOrEqualBoolean();
var result = Sse2.CompareScalarUnorderedLessThanOrEqual(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedLessThanOrEqualBoolean();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedLessThanOrEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedLessThanOrEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse2.CompareScalarUnorderedLessThanOrEqual(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] <= right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareScalarUnorderedLessThanOrEqual)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedNotEqual.Boolean.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedNotEqual.Boolean.cs
index f13dc85baa..5cee6a3f23 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedNotEqual.Boolean.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareScalarUnorderedNotEqual.Boolean.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void CompareScalarUnorderedNotEqualBoolean()
{
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedNotEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedNotEqualBoolean();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanComparisonOpTest__CompareScalarUnorderedNotEqualBoolean
+ public sealed unsafe class BooleanBinaryOpTest__CompareScalarUnorderedNotEqualBoolean
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanComparisonOpTest__CompareScalarUnorderedNotEqualBoolean testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__CompareScalarUnorderedNotEqualBoolean testClass)
{
var result = Sse2.CompareScalarUnorderedNotEqual(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__CompareScalarUnorderedNotEqualBoolean testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedNotEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private BooleanComparisonOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
- static BooleanComparisonOpTest__CompareScalarUnorderedNotEqualBoolean()
+ static BooleanBinaryOpTest__CompareScalarUnorderedNotEqualBoolean()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
- public BooleanComparisonOpTest__CompareScalarUnorderedNotEqualBoolean()
+ public BooleanBinaryOpTest__CompareScalarUnorderedNotEqualBoolean()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new BooleanComparisonOpTest__DataTable<Double, Double>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -244,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse2.CompareScalarUnorderedNotEqual(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareScalarUnorderedNotEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareScalarUnorderedNotEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarUnorderedNotEqual(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarUnorderedNotEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareScalarUnorderedNotEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareScalarUnorderedNotEqual(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanComparisonOpTest__CompareScalarUnorderedNotEqualBoolean();
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedNotEqualBoolean();
var result = Sse2.CompareScalarUnorderedNotEqual(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__CompareScalarUnorderedNotEqualBoolean();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedNotEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -296,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse2.CompareScalarUnorderedNotEqual(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -305,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse2.CompareScalarUnorderedNotEqual(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -313,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -334,36 +495,43 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Double[] left, Double[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
if ((left[0] != right[0]) != result)
{
+ succeeded = false;
+ }
+
+ if (!succeeded)
+ {
TestLibrary.TestFramework.LogInformation($"{nameof(Sse2)}.{nameof(Sse2.CompareScalarUnorderedNotEqual)}<Boolean>(Vector128<Double>, Vector128<Double>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered.Double.cs
index 4030b60e8a..f20016329d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/CompareUnordered.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareUnorderedDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareUnorderedDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.CompareUnordered(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.CompareUnordered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareUnordered(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareUnordered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.CompareUnordered(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.CompareUnordered(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide.Double.cs
index 351c77a49c..b93c8dc1a1 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Divide.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__DivideDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__DivideDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.Divide(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Divide(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.Divide(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Divide(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.Divide(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Divide(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar.Double.cs
index b91a9e26fa..a3d8675180 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/DivideScalar.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__DivideScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__DivideScalarDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.DivideScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.DivideScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.DivideScalar(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.DivideScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.DivideScalar(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.DivideScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Byte.cs
index b534b2ad94..417afc6716 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse2.Max(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Max(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Max(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Double.cs
index 0221d82a84..1584f5ed9a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.Max(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.Max(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.Max(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Int16.cs
index dd49e4b37a..041e008914 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Max.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.Max(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Max(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Max(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar.Double.cs
index 782fa6a75b..e384ed9735 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MaxScalar.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxScalarDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.MaxScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.MaxScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.MaxScalar(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MaxScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.MaxScalar(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MaxScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Byte.cs
index 3cfdd1085e..f401d73687 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse2.Min(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Min(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Min(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Double.cs
index 2efdfebece..2783275b3d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.Min(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.Min(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.Min(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Int16.cs
index 4ee75f195c..d8b9e9e86a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Min.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.Min(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Min(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Min(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar.Double.cs
index d9cacfcd04..0658eea2c1 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MinScalar.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinScalarDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.MinScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.MinScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.MinScalar(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MinScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.MinScalar(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MinScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.Double.cs
index 4392bf21e3..2b630f9b05 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Multiply.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.Multiply(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Multiply(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.Multiply(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Multiply(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.Multiply(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Multiply(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyAddAdjacent.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyAddAdjacent.Int32.cs
index f1e5eed596..7fcc22b765 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyAddAdjacent.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyAddAdjacent.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyAddAdjacentInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyAddAdjacentInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int16, Int16>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.MultiplyAddAdjacent(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.MultiplyAddAdjacent(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.MultiplyAddAdjacent(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MultiplyAddAdjacent(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.MultiplyAddAdjacent(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MultiplyAddAdjacent(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyLow.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyLow.Int16.cs
index c1b502cbb7..d967e1410e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyLow.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyLow.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyLowInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyLowInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.MultiplyLow(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.MultiplyLow(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.MultiplyLow(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyLow.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyLow.UInt16.cs
index 575224186c..ad86d2c4d0 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyLow.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyLow.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyLowUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyLowUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse2.MultiplyLow(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.MultiplyLow(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.MultiplyLow(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar.Double.cs
index f2277472ab..97fb683a91 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/MultiplyScalar.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyScalarDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.MultiplyScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.MultiplyScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.MultiplyScalar(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MultiplyScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.MultiplyScalar(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.MultiplyScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Byte.cs
index e71da18747..6a5347a0a1 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse2.Or(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Double.cs
index 73e9688644..08526a9396 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.Or(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int16.cs
index 7b78dac481..a954b20c3e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.Or(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int32.cs
index 4d5bfcb662..ba44c87782 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse2.Or(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int64.cs
index 82a5cda618..34ef9e7834 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int64> _fld1;
private Vector128<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var result = Sse2.Or(left, right);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, Vector128<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.SByte.cs
index 65c83b54ab..16a123c45e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse2.Or(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt16.cs
index 0742319f5b..1ccd2f8819 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse2.Or(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt32.cs
index a7f1fffae7..ad82295afe 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse2.Or(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt64.cs
index 10a2cb3f87..807ac2cd9e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Or.UInt64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__OrUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt64> _fld1;
private Vector128<UInt64> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__OrUInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
- var result = Sse2.Or(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse2.Or(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Or(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, Vector128<UInt64> op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.Int16.cs
index 1578d93681..0db202dc31 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__PackSignedSaturateInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__PackSignedSaturateInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int32, Int32>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse2.PackSignedSaturate(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.PackSignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.PackSignedSaturate(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.PackSignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.PackSignedSaturate(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.PackSignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.SByte.cs
index f9b4a98d09..2a2410248e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackSignedSaturate.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__PackSignedSaturateSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__PackSignedSaturateSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, Int16, Int16>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.PackSignedSaturate(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.PackSignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.PackSignedSaturate(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.PackSignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.PackSignedSaturate(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.PackSignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackUnsignedSaturate.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackUnsignedSaturate.Byte.cs
index 63ae39a6bf..8d8027b292 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackUnsignedSaturate.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/PackUnsignedSaturate.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__PackUnsignedSaturateByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__PackUnsignedSaturateByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Int16, Int16>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.PackUnsignedSaturate(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.PackUnsignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.PackUnsignedSaturate(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.PackUnsignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.PackUnsignedSaturate(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.PackUnsignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj
index fb09352256..7c0793ef09 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_r.csproj
@@ -276,12 +276,11 @@
<Compile Include="Xor.UInt64.cs" />
<Compile Include="Program.Sse2.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\BooleanCmpOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
<Compile Include="..\Shared\ScalarSimdUnOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimdScalarUnOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleBinOpConvTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
<Compile Include="Sse2Verify.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj
index b9efd1b536..929c71e80b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Sse2_ro.csproj
@@ -276,12 +276,11 @@
<Compile Include="Xor.UInt64.cs" />
<Compile Include="Program.Sse2.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\BooleanCmpOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
<Compile Include="..\Shared\ScalarSimdUnOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimdScalarUnOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleBinOpConvTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
<Compile Include="Sse2Verify.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Byte.cs
index 57b6b9e4da..4ece04c548 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Double.cs
index 288210a50a..7ebb559aa8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int16.cs
index 09c4f01d86..1f186b0458 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int32.cs
index 290db0ec2c..8cb28ab5fb 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int64.cs
index a08f7cb8b1..5d81830c63 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int64> _fld1;
private Vector128<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var result = Sse2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, Vector128<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.SByte.cs
index 583bfd9a87..7ed23e3346 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt16.cs
index bc5015cbc5..e47b039bc1 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt32.cs
index 89b4961d4a..85eed76fcf 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt64.cs
index 61fd50db5c..09214fab60 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Subtract.UInt64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt64> _fld1;
private Vector128<UInt64> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractUInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
- var result = Sse2.Subtract(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse2.Subtract(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Subtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, Vector128<UInt64> op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Byte.cs
index 8c77e12ac6..0a0ed4e678 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractSaturateByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractSaturateByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse2.SubtractSaturate(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.SubtractSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.SubtractSaturate(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.SubtractSaturate(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Int16.cs
index 4a3bed1891..d51297f4f4 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractSaturateInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractSaturateInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.SubtractSaturate(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.SubtractSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.SubtractSaturate(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.SubtractSaturate(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.SByte.cs
index 4551045f0e..8da1fab719 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractSaturateSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractSaturateSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse2.SubtractSaturate(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.SubtractSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.SubtractSaturate(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.SubtractSaturate(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.UInt16.cs
index 4e67455244..7122ecebc2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractSaturate.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractSaturateUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractSaturateUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse2.SubtractSaturate(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.SubtractSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.SubtractSaturate(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.SubtractSaturate(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar.Double.cs
index 9340da79ae..6af1c94711 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SubtractScalar.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SubtractScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SubtractScalarDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.SubtractScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.SubtractScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.SubtractScalar(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.SubtractScalar(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SubtractScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SumAbsoluteDifferences.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SumAbsoluteDifferences.UInt16.cs
index bc607882cd..4c54d1075b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SumAbsoluteDifferences.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/SumAbsoluteDifferences.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SumAbsoluteDifferencesUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SumAbsoluteDifferencesUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, Byte, Byte>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse2.SumAbsoluteDifferences(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.SumAbsoluteDifferences(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.SumAbsoluteDifferences(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SumAbsoluteDifferences(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.SumAbsoluteDifferences(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.SumAbsoluteDifferences(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Byte.cs
index 460fd2592f..ffb08b70ea 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackHighByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackHighByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Double.cs
index 3396b41c6b..4ba228d960 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackHighDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackHighDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int16.cs
index 02c2f2adbf..cea24b61c5 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackHighInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackHighInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int32.cs
index 5963288af7..eb575ac7cb 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackHighInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackHighInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int64.cs
index 33d53f9470..7f55c5a1b2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackHighInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int64> _fld1;
private Vector128<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackHighInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, Vector128<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.SByte.cs
index 4a08a42fe8..2d5569fa44 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackHighSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackHighSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt16.cs
index 29e9fbd60c..3f81f75c4b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackHighUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackHighUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt32.cs
index 3aba08d0ff..06bb6e9a74 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackHighUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackHighUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt64.cs
index 5cb8f507e3..7ab36494e5 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackHigh.UInt64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackHighUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt64> _fld1;
private Vector128<UInt64> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackHighUInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackHigh(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackHigh(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, Vector128<UInt64> op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Byte.cs
index cafddb7c08..83e940347f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackLowByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackLowByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Double.cs
index 9ba49772cf..3c67fd3196 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackLowDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackLowDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int16.cs
index ef771e1348..5e0a0c569a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackLowInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackLowInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int32.cs
index 1d8a5bd6a5..c51f63852c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackLowInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackLowInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int64.cs
index 65b8f7762a..e7991e3383 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackLowInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int64> _fld1;
private Vector128<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackLowInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, Vector128<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.SByte.cs
index f0729a5956..3a1f066619 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackLowSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackLowSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt16.cs
index df8308414e..19472227e2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackLowUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackLowUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt32.cs
index 9198025b6f..ca7ef3e73b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackLowUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackLowUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt64.cs
index 50ff582793..56eb681d60 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/UnpackLow.UInt64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__UnpackLowUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt64> _fld1;
private Vector128<UInt64> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__UnpackLowUInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse2.UnpackLow(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.UnpackLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, Vector128<UInt64> op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Byte.cs
index 3c31f90a27..286638e1e0 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Double.cs
index 44e4168f6d..85e0ba0d0e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int16.cs
index fb24ad883a..a045db8ec0 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int32.cs
index 0bb3c2a166..ca187d2f28 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int64.cs
index 7bbdaac622..32020f8dbc 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int64> _fld1;
private Vector128<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var result = Sse2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, Vector128<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.SByte.cs
index 7ad80f184d..556489f253 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt16.cs
index 07c16a6771..ea45d44f32 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt32.cs
index 4832879aac..428b2f7d7c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt64.cs
index ca560e0141..f6d1747a26 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse2/Xor.UInt64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__XorUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt64> _fld1;
private Vector128<UInt64> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__XorUInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse2.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
- var result = Sse2.Xor(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse2.Xor(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse2.Xor(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, Vector128<UInt64> op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse3/AddSubtract.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse3/AddSubtract.Double.cs
index 654ef64453..2471fa1ea2 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse3/AddSubtract.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse3/AddSubtract.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class AlternatingBinaryOpTest__AddSubtractDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -115,6 +198,21 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(AlternatingBinaryOpTest__AddSubtractDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse3.AddSubtract(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -132,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private AlternatingBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static AlternatingBinaryOpTest__AddSubtractDouble()
{
@@ -153,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new AlternatingBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse3.IsSupported;
@@ -254,40 +352,57 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse3.AddSubtract(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse3.AddSubtract(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse3.AddSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse3.AddSubtract(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse3.AddSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse3.AddSubtract(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse3.AddSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -301,6 +416,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new AlternatingBinaryOpTest__AddSubtractDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ {
+ var result = Sse3.AddSubtract(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -311,6 +445,23 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse3.AddSubtract(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -322,6 +473,20 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse3.AddSubtract(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -330,6 +495,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -351,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse3/AddSubtract.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse3/AddSubtract.Single.cs
index 0b07811294..0effb497b6 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse3/AddSubtract.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse3/AddSubtract.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class AlternatingBinaryOpTest__AddSubtractSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -115,6 +198,21 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(AlternatingBinaryOpTest__AddSubtractSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse3.AddSubtract(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -132,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private AlternatingBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static AlternatingBinaryOpTest__AddSubtractSingle()
{
@@ -153,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new AlternatingBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse3.IsSupported;
@@ -254,40 +352,57 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse3.AddSubtract(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse3.AddSubtract(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse3.AddSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse3.AddSubtract(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse3.AddSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse3.AddSubtract(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse3.AddSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -301,6 +416,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new AlternatingBinaryOpTest__AddSubtractSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ {
+ var result = Sse3.AddSubtract(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -311,6 +445,23 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse3.AddSubtract(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -322,6 +473,20 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse3.AddSubtract(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -330,6 +495,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -351,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalAdd.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalAdd.Double.cs
index 38917133cd..c782da408f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalAdd.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalAdd.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class HorizontalBinaryOpTest__HorizontalAddDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -115,6 +198,21 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(HorizontalBinaryOpTest__HorizontalAddDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse3.HorizontalAdd(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -132,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private HorizontalBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static HorizontalBinaryOpTest__HorizontalAddDouble()
{
@@ -153,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new HorizontalBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse3.IsSupported;
@@ -254,40 +352,57 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse3.HorizontalAdd(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse3.HorizontalAdd(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse3.HorizontalAdd(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse3.HorizontalAdd(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse3.HorizontalAdd(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse3.HorizontalAdd(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse3.HorizontalAdd(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -301,6 +416,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new HorizontalBinaryOpTest__HorizontalAddDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ {
+ var result = Sse3.HorizontalAdd(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -311,6 +445,23 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse3.HorizontalAdd(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -322,6 +473,20 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse3.HorizontalAdd(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -330,6 +495,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -351,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalAdd.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalAdd.Single.cs
index 10b76a4888..478a542440 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalAdd.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalAdd.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class HorizontalBinaryOpTest__HorizontalAddSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -115,6 +198,21 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(HorizontalBinaryOpTest__HorizontalAddSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse3.HorizontalAdd(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -132,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private HorizontalBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static HorizontalBinaryOpTest__HorizontalAddSingle()
{
@@ -153,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new HorizontalBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse3.IsSupported;
@@ -254,40 +352,57 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse3.HorizontalAdd(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse3.HorizontalAdd(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse3.HorizontalAdd(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse3.HorizontalAdd(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse3.HorizontalAdd(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse3.HorizontalAdd(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse3.HorizontalAdd(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -301,6 +416,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new HorizontalBinaryOpTest__HorizontalAddSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ {
+ var result = Sse3.HorizontalAdd(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -311,6 +445,23 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse3.HorizontalAdd(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -322,6 +473,20 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse3.HorizontalAdd(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -330,6 +495,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -351,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalSubtract.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalSubtract.Double.cs
index 04299dacd0..345641b5cd 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalSubtract.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalSubtract.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class HorizontalBinaryOpTest__HorizontalSubtractDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -115,6 +198,21 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(HorizontalBinaryOpTest__HorizontalSubtractDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse3.HorizontalSubtract(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -132,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private HorizontalBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static HorizontalBinaryOpTest__HorizontalSubtractDouble()
{
@@ -153,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new HorizontalBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse3.IsSupported;
@@ -254,40 +352,57 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse3.HorizontalSubtract(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse3.HorizontalSubtract(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse3.HorizontalSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse3.HorizontalSubtract(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse3.HorizontalSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse3.HorizontalSubtract(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse3.HorizontalSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -301,6 +416,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new HorizontalBinaryOpTest__HorizontalSubtractDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ {
+ var result = Sse3.HorizontalSubtract(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -311,6 +445,23 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ {
+ var result = Sse3.HorizontalSubtract(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -322,6 +473,20 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse3.HorizontalSubtract(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -330,6 +495,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -351,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalSubtract.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalSubtract.Single.cs
index 9cfa01ee46..f94289e305 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalSubtract.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse3/HorizontalSubtract.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class HorizontalBinaryOpTest__HorizontalSubtractSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -115,6 +198,21 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(HorizontalBinaryOpTest__HorizontalSubtractSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse3.HorizontalSubtract(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -132,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private HorizontalBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static HorizontalBinaryOpTest__HorizontalSubtractSingle()
{
@@ -153,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new HorizontalBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse3.IsSupported;
@@ -254,40 +352,57 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse3.HorizontalSubtract(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse3.HorizontalSubtract(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse3.HorizontalSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse3.HorizontalSubtract(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse3.HorizontalSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse3.HorizontalSubtract(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse3.HorizontalSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -301,6 +416,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new HorizontalBinaryOpTest__HorizontalSubtractSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ {
+ var result = Sse3.HorizontalSubtract(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -311,6 +445,23 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ {
+ var result = Sse3.HorizontalSubtract(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -322,6 +473,20 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse3.HorizontalSubtract(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -330,6 +495,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -351,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse3/Sse3_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse3/Sse3_r.csproj
index 0245ea6e8b..ed56544eca 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse3/Sse3_r.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse3/Sse3_r.csproj
@@ -35,8 +35,6 @@
<Compile Include="HorizontalSubtract.Single.cs" />
<Compile Include="Program.Sse3.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\AlternatingBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\HorizontalBinOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse3/Sse3_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse3/Sse3_ro.csproj
index fc2a37d3d8..619fce9dec 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse3/Sse3_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse3/Sse3_ro.csproj
@@ -35,8 +35,6 @@
<Compile Include="HorizontalSubtract.Single.cs" />
<Compile Include="Program.Sse3.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\AlternatingBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\HorizontalBinOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41.X64/Sse41.X64_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse41.X64/Sse41.X64_r.csproj
index 4e5f4145bb..1209c0bdcf 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41.X64/Sse41.X64_r.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41.X64/Sse41.X64_r.csproj
@@ -39,7 +39,6 @@
<Compile Include="..\Shared\Program.cs" />
<Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41.X64/Sse41.X64_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse41.X64/Sse41.X64_ro.csproj
index c75f15b944..e7746ffe4c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41.X64/Sse41.X64_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41.X64/Sse41.X64_ro.csproj
@@ -39,7 +39,6 @@
<Compile Include="..\Shared\Program.cs" />
<Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Byte.cs
index 086b6f2a14..9604d56707 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Byte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] inArray3, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Byte, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (byte)(((i % 2) == 0) ? 128 : 1); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar3), ref Unsafe.As<Byte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld3), ref Unsafe.As<Byte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableByte testClass)
+ {
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ fixed (Vector128<Byte>* pFld2 = &_fld2)
+ fixed (Vector128<Byte>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2)),
+ Sse2.LoadVector128((Byte*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld2;
private Vector128<Byte> _fld3;
- private SimpleTernaryOpTest__DataTable<Byte, Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableByte()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (byte)(((i % 2) == 0) ? 128 : 1); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Byte, Byte, Byte, Byte>(_data1, _data2, _data3, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Byte>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Byte>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Byte>* pClsVar3 = &_clsVar3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Byte*)(pClsVar1)),
+ Sse2.LoadVector128((Byte*)(pClsVar2)),
+ Sse2.LoadVector128((Byte*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray3Ptr);
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray3Ptr);
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((Byte*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((Byte*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableByte();
+
+ fixed (Vector128<Byte>* pFld1 = &test._fld1)
+ fixed (Vector128<Byte>* pFld2 = &test._fld2)
+ fixed (Vector128<Byte>* pFld3 = &test._fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2)),
+ Sse2.LoadVector128((Byte*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ fixed (Vector128<Byte>* pFld2 = &_fld2)
+ fixed (Vector128<Byte>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2)),
+ Sse2.LoadVector128((Byte*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Byte*)(&test._fld1)),
+ Sse2.LoadVector128((Byte*)(&test._fld2)),
+ Sse2.LoadVector128((Byte*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> firstOp, Vector128<Byte> secondOp, Vector128<Byte> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, Vector128<Byte> op3, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] inArray3 = new Byte[Op3ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] inArray3 = new Byte[Op3ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.BlendVariable)}<Byte>(Vector128<Byte>, Vector128<Byte>, Vector128<Byte>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Double.cs
index ba2c454f1a..b546296fdd 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] inArray3, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Double, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld2), ref Unsafe.As<Double, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (double)(((i % 2) == 0) ? -0.0 : 1.0); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld3), ref Unsafe.As<Double, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld2;
private Vector128<Double> _fld3;
- private SimpleTernaryOpTest__DataTable<Double, Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableDouble()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (double)(((i % 2) == 0) ? -0.0 : 1.0); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Double, Double, Double, Double>(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Double>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Double>* pClsVar3 = &_clsVar3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Double*)(pClsVar1)),
+ Sse2.LoadVector128((Double*)(pClsVar2)),
+ Sse2.LoadVector128((Double*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray3Ptr);
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ fixed (Vector128<Double>* pFld2 = &test._fld2)
+ fixed (Vector128<Double>* pFld3 = &test._fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ fixed (Vector128<Double>* pFld2 = &_fld2)
+ fixed (Vector128<Double>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Double*)(pFld1)),
+ Sse2.LoadVector128((Double*)(pFld2)),
+ Sse2.LoadVector128((Double*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Double*)(&test._fld1)),
+ Sse2.LoadVector128((Double*)(&test._fld2)),
+ Sse2.LoadVector128((Double*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, Vector128<Double> secondOp, Vector128<Double> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, Vector128<Double> op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] inArray3 = new Double[Op3ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.BlendVariable)}<Double>(Vector128<Double>, Vector128<Double>, Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Int16.cs
index 642e55bf6b..75dfa72272 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Int16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] inArray3, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Int16, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToInt16("0xFFFF", 16) : (short)0); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar3), ref Unsafe.As<Int16, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld3), ref Unsafe.As<Int16, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableInt16 testClass)
+ {
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ fixed (Vector128<Int16>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2)),
+ Sse2.LoadVector128((Int16*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld2;
private Vector128<Int16> _fld3;
- private SimpleTernaryOpTest__DataTable<Int16, Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableInt16()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToInt16("0xFFFF", 16) : (short)0); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Int16, Int16, Int16, Int16>(_data1, _data2, _data3, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int16>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int16>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Int16>* pClsVar3 = &_clsVar3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Int16*)(pClsVar1)),
+ Sse2.LoadVector128((Int16*)(pClsVar2)),
+ Sse2.LoadVector128((Int16*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray3Ptr);
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray3Ptr);
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((Int16*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((Int16*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableInt16();
+
+ fixed (Vector128<Int16>* pFld1 = &test._fld1)
+ fixed (Vector128<Int16>* pFld2 = &test._fld2)
+ fixed (Vector128<Int16>* pFld3 = &test._fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2)),
+ Sse2.LoadVector128((Int16*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ fixed (Vector128<Int16>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2)),
+ Sse2.LoadVector128((Int16*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Int16*)(&test._fld1)),
+ Sse2.LoadVector128((Int16*)(&test._fld2)),
+ Sse2.LoadVector128((Int16*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> firstOp, Vector128<Int16> secondOp, Vector128<Int16> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, Vector128<Int16> op3, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] inArray3 = new Int16[Op3ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] inArray3 = new Int16[Op3ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.BlendVariable)}<Int16>(Vector128<Int16>, Vector128<Int16>, Vector128<Int16>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Int32.cs
index 907e84989f..fca0a4487c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Int32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] inArray3, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Int32, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref testStruct._fld2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToInt32("0xFFFFFFFF", 16) : (int)0); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar3), ref Unsafe.As<Int32, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref testStruct._fld3), ref Unsafe.As<Int32, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableInt32 testClass)
+ {
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ fixed (Vector128<Int32>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2)),
+ Sse2.LoadVector128((Int32*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld2;
private Vector128<Int32> _fld3;
- private SimpleTernaryOpTest__DataTable<Int32, Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableInt32()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToInt32("0xFFFFFFFF", 16) : (int)0); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Int32, Int32, Int32, Int32>(_data1, _data2, _data3, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int32>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int32>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Int32>* pClsVar3 = &_clsVar3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Int32*)(pClsVar1)),
+ Sse2.LoadVector128((Int32*)(pClsVar2)),
+ Sse2.LoadVector128((Int32*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray3Ptr);
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray3Ptr);
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((Int32*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((Int32*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableInt32();
+
+ fixed (Vector128<Int32>* pFld1 = &test._fld1)
+ fixed (Vector128<Int32>* pFld2 = &test._fld2)
+ fixed (Vector128<Int32>* pFld3 = &test._fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2)),
+ Sse2.LoadVector128((Int32*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ fixed (Vector128<Int32>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2)),
+ Sse2.LoadVector128((Int32*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Int32*)(&test._fld1)),
+ Sse2.LoadVector128((Int32*)(&test._fld2)),
+ Sse2.LoadVector128((Int32*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> firstOp, Vector128<Int32> secondOp, Vector128<Int32> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, Vector128<Int32> op3, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] inArray3 = new Int32[Op3ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] inArray3 = new Int32[Op3ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.BlendVariable)}<Int32>(Vector128<Int32>, Vector128<Int32>, Vector128<Int32>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Int64.cs
index e6b4531787..9c4032995c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Int64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] inArray3, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Int64, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int64> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToInt64("0xFFFFFFFFFFFFFFFF", 16) : (long)0); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar3), ref Unsafe.As<Int64, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld3), ref Unsafe.As<Int64, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableInt64 testClass)
+ {
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ fixed (Vector128<Int64>* pFld2 = &_fld2)
+ fixed (Vector128<Int64>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2)),
+ Sse2.LoadVector128((Int64*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int64> _fld2;
private Vector128<Int64> _fld3;
- private SimpleTernaryOpTest__DataTable<Int64, Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableInt64()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToInt64("0xFFFFFFFFFFFFFFFF", 16) : (long)0); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Int64, Int64, Int64, Int64>(_data1, _data2, _data3, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int64>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int64>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Int64>* pClsVar3 = &_clsVar3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Int64*)(pClsVar1)),
+ Sse2.LoadVector128((Int64*)(pClsVar2)),
+ Sse2.LoadVector128((Int64*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray3Ptr);
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray3Ptr);
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((Int64*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((Int64*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableInt64();
+
+ fixed (Vector128<Int64>* pFld1 = &test._fld1)
+ fixed (Vector128<Int64>* pFld2 = &test._fld2)
+ fixed (Vector128<Int64>* pFld3 = &test._fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2)),
+ Sse2.LoadVector128((Int64*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ fixed (Vector128<Int64>* pFld2 = &_fld2)
+ fixed (Vector128<Int64>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2)),
+ Sse2.LoadVector128((Int64*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((Int64*)(&test._fld1)),
+ Sse2.LoadVector128((Int64*)(&test._fld2)),
+ Sse2.LoadVector128((Int64*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> firstOp, Vector128<Int64> secondOp, Vector128<Int64> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, Vector128<Int64> op2, Vector128<Int64> op3, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] inArray3 = new Int64[Op3ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] inArray3 = new Int64[Op3ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.BlendVariable)}<Int64>(Vector128<Int64>, Vector128<Int64>, Vector128<Int64>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.SByte.cs
index 80674e40c5..0cc23da3cf 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.SByte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] inArray3, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<SByte, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (sbyte)(((i % 2) == 0) ? -128 : 1); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar3), ref Unsafe.As<SByte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld3), ref Unsafe.As<SByte, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableSByte testClass)
+ {
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ fixed (Vector128<SByte>* pFld2 = &_fld2)
+ fixed (Vector128<SByte>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2)),
+ Sse2.LoadVector128((SByte*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld2;
private Vector128<SByte> _fld3;
- private SimpleTernaryOpTest__DataTable<SByte, SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableSByte()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (sbyte)(((i % 2) == 0) ? -128 : 1); }
- _dataTable = new SimpleTernaryOpTest__DataTable<SByte, SByte, SByte, SByte>(_data1, _data2, _data3, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<SByte>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<SByte>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<SByte>* pClsVar3 = &_clsVar3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((SByte*)(pClsVar1)),
+ Sse2.LoadVector128((SByte*)(pClsVar2)),
+ Sse2.LoadVector128((SByte*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray3Ptr);
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray3Ptr);
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((SByte*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((SByte*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableSByte();
+
+ fixed (Vector128<SByte>* pFld1 = &test._fld1)
+ fixed (Vector128<SByte>* pFld2 = &test._fld2)
+ fixed (Vector128<SByte>* pFld3 = &test._fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2)),
+ Sse2.LoadVector128((SByte*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ fixed (Vector128<SByte>* pFld2 = &_fld2)
+ fixed (Vector128<SByte>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2)),
+ Sse2.LoadVector128((SByte*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((SByte*)(&test._fld1)),
+ Sse2.LoadVector128((SByte*)(&test._fld2)),
+ Sse2.LoadVector128((SByte*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> firstOp, Vector128<SByte> secondOp, Vector128<SByte> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, Vector128<SByte> op3, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] inArray3 = new SByte[Op3ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] inArray3 = new SByte[Op3ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.BlendVariable)}<SByte>(Vector128<SByte>, Vector128<SByte>, Vector128<SByte>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Single.cs
index 5e8893ba20..f513033d8b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] inArray3, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<Single, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld2), ref Unsafe.As<Single, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (float)(((i % 2) == 0) ? -0.0 : 1.0); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld3), ref Unsafe.As<Single, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld2;
private Vector128<Single> _fld3;
- private SimpleTernaryOpTest__DataTable<Single, Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableSingle()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (float)(((i % 2) == 0) ? -0.0 : 1.0); }
- _dataTable = new SimpleTernaryOpTest__DataTable<Single, Single, Single, Single>(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Single>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<Single>* pClsVar3 = &_clsVar3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse.LoadVector128((Single*)(pClsVar1)),
+ Sse.LoadVector128((Single*)(pClsVar2)),
+ Sse.LoadVector128((Single*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray3Ptr);
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var secondOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var op3 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ fixed (Vector128<Single>* pFld2 = &test._fld2)
+ fixed (Vector128<Single>* pFld3 = &test._fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ fixed (Vector128<Single>* pFld2 = &_fld2)
+ fixed (Vector128<Single>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse.LoadVector128((Single*)(pFld1)),
+ Sse.LoadVector128((Single*)(pFld2)),
+ Sse.LoadVector128((Single*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.BlendVariable(
+ Sse.LoadVector128((Single*)(&test._fld1)),
+ Sse.LoadVector128((Single*)(&test._fld2)),
+ Sse.LoadVector128((Single*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, Vector128<Single> secondOp, Vector128<Single> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, Vector128<Single> op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] inArray3 = new Single[Op3ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.BlendVariable)}<Single>(Vector128<Single>, Vector128<Single>, Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.UInt16.cs
index 8a90647234..5fccc7df35 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.UInt16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] inArray3, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<UInt16, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToUInt16("0xFFFF", 16) : (ushort)0); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar3), ref Unsafe.As<UInt16, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref testStruct._fld3), ref Unsafe.As<UInt16, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableUInt16 testClass)
+ {
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ fixed (Vector128<UInt16>* pFld2 = &_fld2)
+ fixed (Vector128<UInt16>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2)),
+ Sse2.LoadVector128((UInt16*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld2;
private Vector128<UInt16> _fld3;
- private SimpleTernaryOpTest__DataTable<UInt16, UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableUInt16()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToUInt16("0xFFFF", 16) : (ushort)0); }
- _dataTable = new SimpleTernaryOpTest__DataTable<UInt16, UInt16, UInt16, UInt16>(_data1, _data2, _data3, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt16>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt16>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<UInt16>* pClsVar3 = &_clsVar3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((UInt16*)(pClsVar1)),
+ Sse2.LoadVector128((UInt16*)(pClsVar2)),
+ Sse2.LoadVector128((UInt16*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray3Ptr);
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray3Ptr);
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((UInt16*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableUInt16();
+
+ fixed (Vector128<UInt16>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt16>* pFld2 = &test._fld2)
+ fixed (Vector128<UInt16>* pFld3 = &test._fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2)),
+ Sse2.LoadVector128((UInt16*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ fixed (Vector128<UInt16>* pFld2 = &_fld2)
+ fixed (Vector128<UInt16>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2)),
+ Sse2.LoadVector128((UInt16*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((UInt16*)(&test._fld1)),
+ Sse2.LoadVector128((UInt16*)(&test._fld2)),
+ Sse2.LoadVector128((UInt16*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> firstOp, Vector128<UInt16> secondOp, Vector128<UInt16> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, Vector128<UInt16> op3, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] inArray3 = new UInt16[Op3ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] inArray3 = new UInt16[Op3ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.BlendVariable)}<UInt16>(Vector128<UInt16>, Vector128<UInt16>, Vector128<UInt16>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.UInt32.cs
index a83b016541..3129e83e4e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.UInt32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] inArray3, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<UInt32, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToUInt32("0xFFFFFFFF", 16) : (uint)0); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar3), ref Unsafe.As<UInt32, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref testStruct._fld3), ref Unsafe.As<UInt32, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableUInt32 testClass)
+ {
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ fixed (Vector128<UInt32>* pFld2 = &_fld2)
+ fixed (Vector128<UInt32>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2)),
+ Sse2.LoadVector128((UInt32*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld2;
private Vector128<UInt32> _fld3;
- private SimpleTernaryOpTest__DataTable<UInt32, UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableUInt32()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToUInt32("0xFFFFFFFF", 16) : (uint)0); }
- _dataTable = new SimpleTernaryOpTest__DataTable<UInt32, UInt32, UInt32, UInt32>(_data1, _data2, _data3, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt32>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt32>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<UInt32>* pClsVar3 = &_clsVar3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((UInt32*)(pClsVar1)),
+ Sse2.LoadVector128((UInt32*)(pClsVar2)),
+ Sse2.LoadVector128((UInt32*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray3Ptr);
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray3Ptr);
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((UInt32*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableUInt32();
+
+ fixed (Vector128<UInt32>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt32>* pFld2 = &test._fld2)
+ fixed (Vector128<UInt32>* pFld3 = &test._fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2)),
+ Sse2.LoadVector128((UInt32*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ fixed (Vector128<UInt32>* pFld2 = &_fld2)
+ fixed (Vector128<UInt32>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2)),
+ Sse2.LoadVector128((UInt32*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((UInt32*)(&test._fld1)),
+ Sse2.LoadVector128((UInt32*)(&test._fld2)),
+ Sse2.LoadVector128((UInt32*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> firstOp, Vector128<UInt32> secondOp, Vector128<UInt32> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, Vector128<UInt32> op3, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] inArray3 = new UInt32[Op3ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] inArray3 = new UInt32[Op3ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.BlendVariable)}<UInt32>(Vector128<UInt32>, Vector128<UInt32>, Vector128<UInt32>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.UInt64.cs
index b3cf1d428d..b90d01da35 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/BlendVariable.UInt64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,67 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleTernaryOpTest__BlendVariableUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] inArray3;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle inHandle3;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] inArray3, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray3 = inArray3.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfinArray3 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.inArray3 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.inHandle3 = GCHandle.Alloc(this.inArray3, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray3Ptr), ref Unsafe.As<UInt64, byte>(ref inArray3[0]), (uint)sizeOfinArray3);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray3Ptr => Align((byte*)(inHandle3.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ inHandle3.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt64> _fld1;
@@ -106,7 +197,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToUInt64("0xFFFFFFFFFFFFFFFF", 16): (ulong)0); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar3), ref Unsafe.As<UInt64, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld3), ref Unsafe.As<UInt64, byte>(ref _data3[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
return testStruct;
}
@@ -118,6 +209,23 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(SimpleTernaryOpTest__BlendVariableUInt64 testClass)
+ {
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ fixed (Vector128<UInt64>* pFld2 = &_fld2)
+ fixed (Vector128<UInt64>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2)),
+ Sse2.LoadVector128((UInt64*)(pFld3))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, _fld3, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -139,7 +247,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt64> _fld2;
private Vector128<UInt64> _fld3;
- private SimpleTernaryOpTest__DataTable<UInt64, UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleTernaryOpTest__BlendVariableUInt64()
{
@@ -165,7 +273,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op3ElementCount; i++) { _data3[i] = (((i % 2) == 0) ? Convert.ToUInt64("0xFFFFFFFFFFFFFFFF", 16): (ulong)0); }
- _dataTable = new SimpleTernaryOpTest__DataTable<UInt64, UInt64, UInt64, UInt64>(_data1, _data2, _data3, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, _data3, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -273,43 +381,62 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt64>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt64>* pClsVar2 = &_clsVar2)
+ fixed (Vector128<UInt64>* pClsVar3 = &_clsVar3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((UInt64*)(pClsVar1)),
+ Sse2.LoadVector128((UInt64*)(pClsVar2)),
+ Sse2.LoadVector128((UInt64*)(pClsVar3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _clsVar3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
- var secondOp = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
- var thirdOp = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray3Ptr);
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var op3 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray3Ptr);
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadVector128((UInt64*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
- var secondOp = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
- var thirdOp = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray3Ptr));
- var result = Sse41.BlendVariable(firstOp, secondOp, thirdOp);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var op3 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray3Ptr));
+ var result = Sse41.BlendVariable(op1, op2, op3);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, secondOp, thirdOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, op3, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -323,6 +450,27 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleTernaryOpTest__BlendVariableUInt64();
+
+ fixed (Vector128<UInt64>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt64>* pFld2 = &test._fld2)
+ fixed (Vector128<UInt64>* pFld3 = &test._fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2)),
+ Sse2.LoadVector128((UInt64*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -333,6 +481,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ fixed (Vector128<UInt64>* pFld2 = &_fld2)
+ fixed (Vector128<UInt64>* pFld3 = &_fld3)
+ {
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2)),
+ Sse2.LoadVector128((UInt64*)(pFld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _fld3, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -344,6 +511,21 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.BlendVariable(
+ Sse2.LoadVector128((UInt64*)(&test._fld1)),
+ Sse2.LoadVector128((UInt64*)(&test._fld2)),
+ Sse2.LoadVector128((UInt64*)(&test._fld3))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, test._fld3, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -352,6 +534,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -373,31 +563,31 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> firstOp, Vector128<UInt64> secondOp, Vector128<UInt64> thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, Vector128<UInt64> op2, Vector128<UInt64> op3, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] inArray3 = new UInt64[Op3ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), firstOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), secondOp);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray3[0]), thirdOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray3[0]), op3);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
}
- private void ValidateResult(void* firstOp, void* secondOp, void* thirdOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* op3, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] inArray3 = new UInt64[Op3ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(secondOp), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(thirdOp), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray3[0]), ref Unsafe.AsRef<byte>(op3), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, inArray3, outArray, method);
@@ -426,10 +616,10 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.BlendVariable)}<UInt64>(Vector128<UInt64>, Vector128<UInt64>, Vector128<UInt64>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" secondOp: ({string.Join(", ", secondOp)})");
- TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($"secondOp: ({string.Join(", ", secondOp)})");
+ TestLibrary.TestFramework.LogInformation($" thirdOp: ({string.Join(", ", thirdOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Ceiling.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Ceiling.Double.cs
index 86ab3a0d9a..2beb934b75 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Ceiling.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Ceiling.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__CeilingDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Double> _fld;
+ public Vector128<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__CeilingDouble testClass)
{
- var result = Sse41.Ceiling(_fld);
+ var result = Sse41.Ceiling(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__CeilingDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Sse41.Ceiling(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector128<Double> _clsVar;
+ private static Vector128<Double> _clsVar1;
- private Vector128<Double> _fld;
+ private Vector128<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__CeilingDouble()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
public SimpleUnaryOpTest__CeilingDouble()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.Ceiling(
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.Ceiling(
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.Ceiling(
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.Ceiling), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.Ceiling), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.Ceiling), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.Ceiling(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.Ceiling(
+ Sse2.LoadVector128((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr);
- var result = Sse41.Ceiling(firstOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var result = Sse41.Ceiling(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr));
- var result = Sse41.Ceiling(firstOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Sse41.Ceiling(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr));
- var result = Sse41.Ceiling(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Sse41.Ceiling(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__CeilingDouble();
- var result = Sse41.Ceiling(test._fld);
+ var result = Sse41.Ceiling(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__CeilingDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.Ceiling(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.Ceiling(_fld);
+ var result = Sse41.Ceiling(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Sse41.Ceiling(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.Ceiling(test._fld);
+ var result = Sse41.Ceiling(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.Ceiling(
+ Sse2.LoadVector128((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.Ceiling)}<Double>(Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Ceiling.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Ceiling.Single.cs
index 15d2128ec3..9f669bf492 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Ceiling.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Ceiling.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__CeilingSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Single> _fld;
+ public Vector128<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__CeilingSingle testClass)
{
- var result = Sse41.Ceiling(_fld);
+ var result = Sse41.Ceiling(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__CeilingSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Sse41.Ceiling(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector128<Single> _clsVar;
+ private static Vector128<Single> _clsVar1;
- private Vector128<Single> _fld;
+ private Vector128<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__CeilingSingle()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
public SimpleUnaryOpTest__CeilingSingle()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.Ceiling(
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.Ceiling(
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.Ceiling(
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.Ceiling), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.Ceiling), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.Ceiling), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.Ceiling(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.Ceiling(
+ Sse.LoadVector128((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
- var result = Sse41.Ceiling(firstOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var result = Sse41.Ceiling(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
- var result = Sse41.Ceiling(firstOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Sse41.Ceiling(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
- var result = Sse41.Ceiling(firstOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Sse41.Ceiling(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__CeilingSingle();
- var result = Sse41.Ceiling(test._fld);
+ var result = Sse41.Ceiling(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__CeilingSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.Ceiling(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.Ceiling(_fld);
+ var result = Sse41.Ceiling(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Sse41.Ceiling(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.Ceiling(test._fld);
+ var result = Sse41.Ceiling(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.Ceiling(
+ Sse.LoadVector128((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.Ceiling)}<Single>(Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/CeilingScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/CeilingScalar.Double.cs
index ff7e935300..09aa95d5a9 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/CeilingScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/CeilingScalar.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CeilingScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CeilingScalarDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse41.CeilingScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse41.CeilingScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse41.CeilingScalar(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse41.CeilingScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse41.CeilingScalar(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse41.CeilingScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/CeilingScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/CeilingScalar.Single.cs
index d54966c17d..6240dacebb 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/CeilingScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/CeilingScalar.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CeilingScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CeilingScalarSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse41.CeilingScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse41.CeilingScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse41.CeilingScalar(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse41.CeilingScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse41.CeilingScalar(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse41.CeilingScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/CompareEqual.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/CompareEqual.Int64.cs
index c48b052334..29bee54f2e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/CompareEqual.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/CompareEqual.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int64> _fld1;
private Vector128<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var result = Sse41.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse41.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse41.CompareEqual(left, right);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse41.CompareEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, Vector128<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/CompareEqual.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/CompareEqual.UInt64.cs
index a351617ce2..51e12717de 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/CompareEqual.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/CompareEqual.UInt64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareEqualUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, UInt64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt64> _fld1;
private Vector128<UInt64> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareEqualUInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt64, UInt64, UInt64>(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
- var result = Sse41.CompareEqual(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse41.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse41.CompareEqual(left, right);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse41.CompareEqual(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.CompareEqual(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, Vector128<UInt64> op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
UInt64[] outArray = new UInt64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Floor.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Floor.Double.cs
index d85d28d78d..3f9742a072 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Floor.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Floor.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__FloorDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Double> _fld;
+ public Vector128<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__FloorDouble testClass)
{
- var result = Sse41.Floor(_fld);
+ var result = Sse41.Floor(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__FloorDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Sse41.Floor(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector128<Double> _clsVar;
+ private static Vector128<Double> _clsVar1;
- private Vector128<Double> _fld;
+ private Vector128<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__FloorDouble()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
public SimpleUnaryOpTest__FloorDouble()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.Floor(
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.Floor(
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.Floor(
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.Floor), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.Floor), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.Floor), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.Floor(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.Floor(
+ Sse2.LoadVector128((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr);
- var result = Sse41.Floor(firstOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var result = Sse41.Floor(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr));
- var result = Sse41.Floor(firstOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Sse41.Floor(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr));
- var result = Sse41.Floor(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Sse41.Floor(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__FloorDouble();
- var result = Sse41.Floor(test._fld);
+ var result = Sse41.Floor(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__FloorDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.Floor(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.Floor(_fld);
+ var result = Sse41.Floor(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Sse41.Floor(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.Floor(test._fld);
+ var result = Sse41.Floor(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.Floor(
+ Sse2.LoadVector128((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.Floor)}<Double>(Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Floor.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Floor.Single.cs
index 595f75e7dc..d7719a17b0 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Floor.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Floor.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__FloorSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Single> _fld;
+ public Vector128<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__FloorSingle testClass)
{
- var result = Sse41.Floor(_fld);
+ var result = Sse41.Floor(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__FloorSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Sse41.Floor(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector128<Single> _clsVar;
+ private static Vector128<Single> _clsVar1;
- private Vector128<Single> _fld;
+ private Vector128<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__FloorSingle()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
public SimpleUnaryOpTest__FloorSingle()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.Floor(
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.Floor(
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.Floor(
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.Floor), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.Floor), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.Floor), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.Floor(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.Floor(
+ Sse.LoadVector128((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
- var result = Sse41.Floor(firstOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var result = Sse41.Floor(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
- var result = Sse41.Floor(firstOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Sse41.Floor(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
- var result = Sse41.Floor(firstOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Sse41.Floor(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__FloorSingle();
- var result = Sse41.Floor(test._fld);
+ var result = Sse41.Floor(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__FloorSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.Floor(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.Floor(_fld);
+ var result = Sse41.Floor(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Sse41.Floor(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.Floor(test._fld);
+ var result = Sse41.Floor(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.Floor(
+ Sse.LoadVector128((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.Floor)}<Single>(Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/FloorScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/FloorScalar.Double.cs
index 27b6c44880..e9bd517fd7 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/FloorScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/FloorScalar.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__FloorScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__FloorScalarDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse41.FloorScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse41.FloorScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse41.FloorScalar(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse41.FloorScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse41.FloorScalar(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse41.FloorScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/FloorScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/FloorScalar.Single.cs
index 45267004f5..a1a48a5e5e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/FloorScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/FloorScalar.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__FloorScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__FloorScalarSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse41.FloorScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse41.FloorScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse41.FloorScalar(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse41.FloorScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse41.FloorScalar(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse41.FloorScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.Int32.cs
index e85b2bf257..16f971a1df 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse41.Max(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.Max(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.Max(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.SByte.cs
index 85a311e006..a81c4342f1 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse41.Max(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse41.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse41.Max(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse41.Max(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.UInt16.cs
index 7551b60176..c7e209c503 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse41.Max(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse41.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse41.Max(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse41.Max(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.UInt32.cs
index d1a0992e32..e698d736b8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Max.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MaxUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MaxUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse41.Max(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse41.Max(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse41.Max(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.Max(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.Int32.cs
index dadd90dfdb..5c67f02a2b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse41.Min(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.Min(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.Min(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.SByte.cs
index eb355fe295..d0e8d8789d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse41.Min(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse41.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse41.Min(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse41.Min(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.UInt16.cs
index 7731fb823f..3e5bc9694d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.UInt16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinUInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt16, UInt16, UInt16>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse41.Min(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse41.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse41.Min(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse41.Min(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.UInt32.cs
index 00fd5e229a..169ecbbe76 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Min.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MinUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MinUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse41.Min(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse41.Min(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse41.Min(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.Min(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/MultiplyLow.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/MultiplyLow.Int32.cs
index bd2386ad24..0b5640b964 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/MultiplyLow.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/MultiplyLow.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyLowInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyLowInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse41.MultiplyLow(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.MultiplyLow(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.MultiplyLow(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/MultiplyLow.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/MultiplyLow.UInt32.cs
index dcb3aba590..4389d72204 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/MultiplyLow.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/MultiplyLow.UInt32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyLowUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyLowUInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<UInt32, UInt32, UInt32>(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse41.MultiplyLow(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse41.MultiplyLow(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse41.MultiplyLow(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.MultiplyLow(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/PackUnsignedSaturate.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/PackUnsignedSaturate.UInt16.cs
index 8e0788db48..5c344bef96 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/PackUnsignedSaturate.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/PackUnsignedSaturate.UInt16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class HorizontalBinaryOpTest__PackUnsignedSaturateUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -115,6 +198,21 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(HorizontalBinaryOpTest__PackUnsignedSaturateUInt16 testClass)
+ {
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.PackUnsignedSaturate(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -132,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private HorizontalBinaryOpTest__DataTable<UInt16, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static HorizontalBinaryOpTest__PackUnsignedSaturateUInt16()
{
@@ -153,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new HorizontalBinaryOpTest__DataTable<UInt16, Int32, Int32>(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -254,40 +352,57 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int32>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.PackUnsignedSaturate(
+ Sse2.LoadVector128((Int32*)(pClsVar1)),
+ Sse2.LoadVector128((Int32*)(pClsVar2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse41.PackUnsignedSaturate(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.PackUnsignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.PackUnsignedSaturate(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.PackUnsignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.PackUnsignedSaturate(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.PackUnsignedSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -301,6 +416,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new HorizontalBinaryOpTest__PackUnsignedSaturateUInt16();
+
+ fixed (Vector128<Int32>* pFld1 = &test._fld1)
+ fixed (Vector128<Int32>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.PackUnsignedSaturate(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -311,6 +445,23 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.PackUnsignedSaturate(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -322,6 +473,20 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.PackUnsignedSaturate(
+ Sse2.LoadVector128((Int32*)(&test._fld1)),
+ Sse2.LoadVector128((Int32*)(&test._fld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -330,6 +495,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -351,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirection.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirection.Double.cs
index 501ee8ebb6..7ad680254c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirection.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirection.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundCurrentDirectionDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Double> _fld;
+ public Vector128<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundCurrentDirectionDouble testClass)
{
- var result = Sse41.RoundCurrentDirection(_fld);
+ var result = Sse41.RoundCurrentDirection(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundCurrentDirectionDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundCurrentDirection(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector128<Double> _clsVar;
+ private static Vector128<Double> _clsVar1;
- private Vector128<Double> _fld;
+ private Vector128<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundCurrentDirectionDouble()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
public SimpleUnaryOpTest__RoundCurrentDirectionDouble()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.RoundCurrentDirection(
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.RoundCurrentDirection(
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.RoundCurrentDirection(
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundCurrentDirection), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundCurrentDirection), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundCurrentDirection), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.RoundCurrentDirection(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.RoundCurrentDirection(
+ Sse2.LoadVector128((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr);
- var result = Sse41.RoundCurrentDirection(firstOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var result = Sse41.RoundCurrentDirection(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundCurrentDirection(firstOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundCurrentDirection(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundCurrentDirection(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundCurrentDirection(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundCurrentDirectionDouble();
- var result = Sse41.RoundCurrentDirection(test._fld);
+ var result = Sse41.RoundCurrentDirection(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundCurrentDirectionDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.RoundCurrentDirection(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.RoundCurrentDirection(_fld);
+ var result = Sse41.RoundCurrentDirection(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundCurrentDirection(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.RoundCurrentDirection(test._fld);
+ var result = Sse41.RoundCurrentDirection(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.RoundCurrentDirection(
+ Sse2.LoadVector128((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.RoundCurrentDirection)}<Double>(Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirection.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirection.Single.cs
index bad5fb98bd..b3a07b788e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirection.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirection.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundCurrentDirectionSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Single> _fld;
+ public Vector128<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundCurrentDirectionSingle testClass)
{
- var result = Sse41.RoundCurrentDirection(_fld);
+ var result = Sse41.RoundCurrentDirection(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundCurrentDirectionSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundCurrentDirection(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector128<Single> _clsVar;
+ private static Vector128<Single> _clsVar1;
- private Vector128<Single> _fld;
+ private Vector128<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundCurrentDirectionSingle()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
public SimpleUnaryOpTest__RoundCurrentDirectionSingle()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.RoundCurrentDirection(
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.RoundCurrentDirection(
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.RoundCurrentDirection(
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundCurrentDirection), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundCurrentDirection), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundCurrentDirection), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.RoundCurrentDirection(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.RoundCurrentDirection(
+ Sse.LoadVector128((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
- var result = Sse41.RoundCurrentDirection(firstOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var result = Sse41.RoundCurrentDirection(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundCurrentDirection(firstOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundCurrentDirection(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundCurrentDirection(firstOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundCurrentDirection(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundCurrentDirectionSingle();
- var result = Sse41.RoundCurrentDirection(test._fld);
+ var result = Sse41.RoundCurrentDirection(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundCurrentDirectionSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.RoundCurrentDirection(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.RoundCurrentDirection(_fld);
+ var result = Sse41.RoundCurrentDirection(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundCurrentDirection(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.RoundCurrentDirection(test._fld);
+ var result = Sse41.RoundCurrentDirection(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.RoundCurrentDirection(
+ Sse.LoadVector128((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.RoundCurrentDirection)}<Single>(Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirectionScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirectionScalar.Double.cs
index d7f7f452f9..a40bc44087 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirectionScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirectionScalar.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__RoundCurrentDirectionScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__RoundCurrentDirectionScalarDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse41.RoundCurrentDirectionScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse41.RoundCurrentDirectionScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundCurrentDirectionScalar(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundCurrentDirectionScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundCurrentDirectionScalar(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundCurrentDirectionScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirectionScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirectionScalar.Single.cs
index 3a7021957b..44e32a96c1 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirectionScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundCurrentDirectionScalar.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__RoundCurrentDirectionScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__RoundCurrentDirectionScalarSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse41.RoundCurrentDirectionScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse41.RoundCurrentDirectionScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundCurrentDirectionScalar(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundCurrentDirectionScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundCurrentDirectionScalar(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundCurrentDirectionScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestInteger.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestInteger.Double.cs
index fdd9ed9294..6ad5061e1a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestInteger.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestInteger.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundToNearestIntegerDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Double> _fld;
+ public Vector128<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundToNearestIntegerDouble testClass)
{
- var result = Sse41.RoundToNearestInteger(_fld);
+ var result = Sse41.RoundToNearestInteger(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundToNearestIntegerDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundToNearestInteger(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector128<Double> _clsVar;
+ private static Vector128<Double> _clsVar1;
- private Vector128<Double> _fld;
+ private Vector128<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundToNearestIntegerDouble()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
public SimpleUnaryOpTest__RoundToNearestIntegerDouble()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.RoundToNearestInteger(
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.RoundToNearestInteger(
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.RoundToNearestInteger(
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToNearestInteger), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToNearestInteger), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToNearestInteger), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.RoundToNearestInteger(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.RoundToNearestInteger(
+ Sse2.LoadVector128((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr);
- var result = Sse41.RoundToNearestInteger(firstOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var result = Sse41.RoundToNearestInteger(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundToNearestInteger(firstOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundToNearestInteger(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundToNearestInteger(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundToNearestInteger(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundToNearestIntegerDouble();
- var result = Sse41.RoundToNearestInteger(test._fld);
+ var result = Sse41.RoundToNearestInteger(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundToNearestIntegerDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.RoundToNearestInteger(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.RoundToNearestInteger(_fld);
+ var result = Sse41.RoundToNearestInteger(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundToNearestInteger(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.RoundToNearestInteger(test._fld);
+ var result = Sse41.RoundToNearestInteger(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.RoundToNearestInteger(
+ Sse2.LoadVector128((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.RoundToNearestInteger)}<Double>(Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestInteger.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestInteger.Single.cs
index 21727d3348..2082c117bd 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestInteger.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestInteger.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundToNearestIntegerSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Single> _fld;
+ public Vector128<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundToNearestIntegerSingle testClass)
{
- var result = Sse41.RoundToNearestInteger(_fld);
+ var result = Sse41.RoundToNearestInteger(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundToNearestIntegerSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundToNearestInteger(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector128<Single> _clsVar;
+ private static Vector128<Single> _clsVar1;
- private Vector128<Single> _fld;
+ private Vector128<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundToNearestIntegerSingle()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
public SimpleUnaryOpTest__RoundToNearestIntegerSingle()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.RoundToNearestInteger(
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.RoundToNearestInteger(
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.RoundToNearestInteger(
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToNearestInteger), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToNearestInteger), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToNearestInteger), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.RoundToNearestInteger(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.RoundToNearestInteger(
+ Sse.LoadVector128((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
- var result = Sse41.RoundToNearestInteger(firstOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var result = Sse41.RoundToNearestInteger(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundToNearestInteger(firstOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundToNearestInteger(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundToNearestInteger(firstOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundToNearestInteger(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundToNearestIntegerSingle();
- var result = Sse41.RoundToNearestInteger(test._fld);
+ var result = Sse41.RoundToNearestInteger(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundToNearestIntegerSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.RoundToNearestInteger(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.RoundToNearestInteger(_fld);
+ var result = Sse41.RoundToNearestInteger(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundToNearestInteger(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.RoundToNearestInteger(test._fld);
+ var result = Sse41.RoundToNearestInteger(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.RoundToNearestInteger(
+ Sse.LoadVector128((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.RoundToNearestInteger)}<Single>(Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestIntegerScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestIntegerScalar.Double.cs
index eddf163461..c8a8cd9b14 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestIntegerScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestIntegerScalar.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__RoundToNearestIntegerScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__RoundToNearestIntegerScalarDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse41.RoundToNearestIntegerScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse41.RoundToNearestIntegerScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundToNearestIntegerScalar(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundToNearestIntegerScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundToNearestIntegerScalar(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundToNearestIntegerScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestIntegerScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestIntegerScalar.Single.cs
index 46708b5111..8004c14bec 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestIntegerScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNearestIntegerScalar.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__RoundToNearestIntegerScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__RoundToNearestIntegerScalarSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse41.RoundToNearestIntegerScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse41.RoundToNearestIntegerScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundToNearestIntegerScalar(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundToNearestIntegerScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundToNearestIntegerScalar(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundToNearestIntegerScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinity.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinity.Double.cs
index b94b9d1d78..b08cc3d4d0 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinity.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinity.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundToNegativeInfinityDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Double> _fld;
+ public Vector128<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundToNegativeInfinityDouble testClass)
{
- var result = Sse41.RoundToNegativeInfinity(_fld);
+ var result = Sse41.RoundToNegativeInfinity(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundToNegativeInfinityDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundToNegativeInfinity(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector128<Double> _clsVar;
+ private static Vector128<Double> _clsVar1;
- private Vector128<Double> _fld;
+ private Vector128<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundToNegativeInfinityDouble()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
public SimpleUnaryOpTest__RoundToNegativeInfinityDouble()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.RoundToNegativeInfinity(
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.RoundToNegativeInfinity(
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.RoundToNegativeInfinity(
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToNegativeInfinity), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToNegativeInfinity), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToNegativeInfinity), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.RoundToNegativeInfinity(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.RoundToNegativeInfinity(
+ Sse2.LoadVector128((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr);
- var result = Sse41.RoundToNegativeInfinity(firstOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var result = Sse41.RoundToNegativeInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundToNegativeInfinity(firstOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundToNegativeInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundToNegativeInfinity(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundToNegativeInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundToNegativeInfinityDouble();
- var result = Sse41.RoundToNegativeInfinity(test._fld);
+ var result = Sse41.RoundToNegativeInfinity(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundToNegativeInfinityDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.RoundToNegativeInfinity(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.RoundToNegativeInfinity(_fld);
+ var result = Sse41.RoundToNegativeInfinity(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundToNegativeInfinity(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.RoundToNegativeInfinity(test._fld);
+ var result = Sse41.RoundToNegativeInfinity(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.RoundToNegativeInfinity(
+ Sse2.LoadVector128((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.RoundToNegativeInfinity)}<Double>(Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinity.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinity.Single.cs
index 0a3a98ae4b..4784eaaa66 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinity.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinity.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundToNegativeInfinitySingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Single> _fld;
+ public Vector128<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundToNegativeInfinitySingle testClass)
{
- var result = Sse41.RoundToNegativeInfinity(_fld);
+ var result = Sse41.RoundToNegativeInfinity(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundToNegativeInfinitySingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundToNegativeInfinity(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector128<Single> _clsVar;
+ private static Vector128<Single> _clsVar1;
- private Vector128<Single> _fld;
+ private Vector128<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundToNegativeInfinitySingle()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
public SimpleUnaryOpTest__RoundToNegativeInfinitySingle()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.RoundToNegativeInfinity(
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.RoundToNegativeInfinity(
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.RoundToNegativeInfinity(
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToNegativeInfinity), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToNegativeInfinity), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToNegativeInfinity), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.RoundToNegativeInfinity(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.RoundToNegativeInfinity(
+ Sse.LoadVector128((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
- var result = Sse41.RoundToNegativeInfinity(firstOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var result = Sse41.RoundToNegativeInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundToNegativeInfinity(firstOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundToNegativeInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundToNegativeInfinity(firstOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundToNegativeInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundToNegativeInfinitySingle();
- var result = Sse41.RoundToNegativeInfinity(test._fld);
+ var result = Sse41.RoundToNegativeInfinity(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundToNegativeInfinitySingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.RoundToNegativeInfinity(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.RoundToNegativeInfinity(_fld);
+ var result = Sse41.RoundToNegativeInfinity(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundToNegativeInfinity(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.RoundToNegativeInfinity(test._fld);
+ var result = Sse41.RoundToNegativeInfinity(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.RoundToNegativeInfinity(
+ Sse.LoadVector128((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.RoundToNegativeInfinity)}<Single>(Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinityScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinityScalar.Double.cs
index d0053b5cb9..28b2340c25 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinityScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinityScalar.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__RoundToNegativeInfinityScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__RoundToNegativeInfinityScalarDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse41.RoundToNegativeInfinityScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse41.RoundToNegativeInfinityScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundToNegativeInfinityScalar(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundToNegativeInfinityScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundToNegativeInfinityScalar(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundToNegativeInfinityScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinityScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinityScalar.Single.cs
index 8e241603e2..0c9b3e6a39 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinityScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToNegativeInfinityScalar.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__RoundToNegativeInfinityScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__RoundToNegativeInfinityScalarSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse41.RoundToNegativeInfinityScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse41.RoundToNegativeInfinityScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundToNegativeInfinityScalar(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundToNegativeInfinityScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundToNegativeInfinityScalar(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundToNegativeInfinityScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinity.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinity.Double.cs
index ee11bda963..922f84bd6e 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinity.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinity.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundToPositiveInfinityDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Double> _fld;
+ public Vector128<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundToPositiveInfinityDouble testClass)
{
- var result = Sse41.RoundToPositiveInfinity(_fld);
+ var result = Sse41.RoundToPositiveInfinity(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundToPositiveInfinityDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundToPositiveInfinity(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector128<Double> _clsVar;
+ private static Vector128<Double> _clsVar1;
- private Vector128<Double> _fld;
+ private Vector128<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundToPositiveInfinityDouble()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
public SimpleUnaryOpTest__RoundToPositiveInfinityDouble()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.RoundToPositiveInfinity(
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.RoundToPositiveInfinity(
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.RoundToPositiveInfinity(
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToPositiveInfinity), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToPositiveInfinity), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToPositiveInfinity), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.RoundToPositiveInfinity(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.RoundToPositiveInfinity(
+ Sse2.LoadVector128((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr);
- var result = Sse41.RoundToPositiveInfinity(firstOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var result = Sse41.RoundToPositiveInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundToPositiveInfinity(firstOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundToPositiveInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundToPositiveInfinity(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundToPositiveInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundToPositiveInfinityDouble();
- var result = Sse41.RoundToPositiveInfinity(test._fld);
+ var result = Sse41.RoundToPositiveInfinity(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundToPositiveInfinityDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.RoundToPositiveInfinity(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.RoundToPositiveInfinity(_fld);
+ var result = Sse41.RoundToPositiveInfinity(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundToPositiveInfinity(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.RoundToPositiveInfinity(test._fld);
+ var result = Sse41.RoundToPositiveInfinity(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.RoundToPositiveInfinity(
+ Sse2.LoadVector128((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.RoundToPositiveInfinity)}<Double>(Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinity.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinity.Single.cs
index 120bccda66..5d977308c8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinity.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinity.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundToPositiveInfinitySingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Single> _fld;
+ public Vector128<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundToPositiveInfinitySingle testClass)
{
- var result = Sse41.RoundToPositiveInfinity(_fld);
+ var result = Sse41.RoundToPositiveInfinity(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundToPositiveInfinitySingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundToPositiveInfinity(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector128<Single> _clsVar;
+ private static Vector128<Single> _clsVar1;
- private Vector128<Single> _fld;
+ private Vector128<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundToPositiveInfinitySingle()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
public SimpleUnaryOpTest__RoundToPositiveInfinitySingle()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.RoundToPositiveInfinity(
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.RoundToPositiveInfinity(
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.RoundToPositiveInfinity(
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToPositiveInfinity), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToPositiveInfinity), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToPositiveInfinity), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.RoundToPositiveInfinity(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.RoundToPositiveInfinity(
+ Sse.LoadVector128((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
- var result = Sse41.RoundToPositiveInfinity(firstOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var result = Sse41.RoundToPositiveInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundToPositiveInfinity(firstOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundToPositiveInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundToPositiveInfinity(firstOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundToPositiveInfinity(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundToPositiveInfinitySingle();
- var result = Sse41.RoundToPositiveInfinity(test._fld);
+ var result = Sse41.RoundToPositiveInfinity(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundToPositiveInfinitySingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.RoundToPositiveInfinity(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.RoundToPositiveInfinity(_fld);
+ var result = Sse41.RoundToPositiveInfinity(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundToPositiveInfinity(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.RoundToPositiveInfinity(test._fld);
+ var result = Sse41.RoundToPositiveInfinity(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.RoundToPositiveInfinity(
+ Sse.LoadVector128((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.RoundToPositiveInfinity)}<Single>(Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinityScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinityScalar.Double.cs
index 6a22bd893f..64e945631a 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinityScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinityScalar.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__RoundToPositiveInfinityScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__RoundToPositiveInfinityScalarDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse41.RoundToPositiveInfinityScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse41.RoundToPositiveInfinityScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundToPositiveInfinityScalar(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundToPositiveInfinityScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundToPositiveInfinityScalar(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundToPositiveInfinityScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinityScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinityScalar.Single.cs
index 3a173744ee..c7d74a2ccb 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinityScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToPositiveInfinityScalar.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__RoundToPositiveInfinityScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__RoundToPositiveInfinityScalarSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse41.RoundToPositiveInfinityScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse41.RoundToPositiveInfinityScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundToPositiveInfinityScalar(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundToPositiveInfinityScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundToPositiveInfinityScalar(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundToPositiveInfinityScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZero.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZero.Double.cs
index 216a2a276b..8e5f7c13c9 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZero.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZero.Double.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundToZeroDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Double> _fld;
+ public Vector128<Double> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref testStruct._fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundToZeroDouble testClass)
{
- var result = Sse41.RoundToZero(_fld);
+ var result = Sse41.RoundToZero(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundToZeroDouble testClass)
+ {
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundToZero(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Double>>() / sizeof(Double);
- private static Double[] _data = new Double[Op1ElementCount];
+ private static Double[] _data1 = new Double[Op1ElementCount];
- private static Vector128<Double> _clsVar;
+ private static Vector128<Double> _clsVar1;
- private Vector128<Double> _fld;
+ private Vector128<Double> _fld1;
- private SimpleUnaryOpTest__DataTable<Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundToZeroDouble()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _clsVar1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
}
public SimpleUnaryOpTest__RoundToZeroDouble()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld), ref Unsafe.As<Double, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Double>, byte>(ref _fld1), ref Unsafe.As<Double, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Double>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Double, Double>(_data, new Double[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
+ _dataTable = new DataTable(_data1, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.RoundToZero(
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.RoundToZero(
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.RoundToZero(
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToZero), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToZero), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToZero), new Type[] { typeof(Vector128<Double>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Double>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.RoundToZero(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Double>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.RoundToZero(
+ Sse2.LoadVector128((Double*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Double>>(_dataTable.inArrayPtr);
- var result = Sse41.RoundToZero(firstOp);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var result = Sse41.RoundToZero(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Double*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundToZero(firstOp);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundToZero(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundToZero(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundToZero(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundToZeroDouble();
- var result = Sse41.RoundToZero(test._fld);
+ var result = Sse41.RoundToZero(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundToZeroDouble();
+
+ fixed (Vector128<Double>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.RoundToZero(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.RoundToZero(_fld);
+ var result = Sse41.RoundToZero(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Double>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundToZero(
+ Sse2.LoadVector128((Double*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.RoundToZero(test._fld);
+ var result = Sse41.RoundToZero(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.RoundToZero(
+ Sse2.LoadVector128((Double*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Double[] inArray = new Double[Op1ElementCount];
+ Double[] inArray1 = new Double[Op1ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Double[] firstOp, Double[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.RoundToZero)}<Double>(Vector128<Double>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZero.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZero.Single.cs
index 850c45568f..60fd438bb1 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZero.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZero.Single.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__RoundToZeroSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Single> _fld;
+ public Vector128<Single> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref testStruct._fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__RoundToZeroSingle testClass)
{
- var result = Sse41.RoundToZero(_fld);
+ var result = Sse41.RoundToZero(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__RoundToZeroSingle testClass)
+ {
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundToZero(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Single>>() / sizeof(Single);
- private static Single[] _data = new Single[Op1ElementCount];
+ private static Single[] _data1 = new Single[Op1ElementCount];
- private static Vector128<Single> _clsVar;
+ private static Vector128<Single> _clsVar1;
- private Vector128<Single> _fld;
+ private Vector128<Single> _fld1;
- private SimpleUnaryOpTest__DataTable<Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__RoundToZeroSingle()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _clsVar1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
}
public SimpleUnaryOpTest__RoundToZeroSingle()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld), ref Unsafe.As<Single, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Single>, byte>(ref _fld1), ref Unsafe.As<Single, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Single>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Single, Single>(_data, new Single[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
+ _dataTable = new DataTable(_data1, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.RoundToZero(
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.RoundToZero(
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.RoundToZero(
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToZero), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToZero), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.RoundToZero), new Type[] { typeof(Vector128<Single>) })
.Invoke(null, new object[] {
- Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr))
+ Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Single>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.RoundToZero(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Single>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.RoundToZero(
+ Sse.LoadVector128((Single*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Single>>(_dataTable.inArrayPtr);
- var result = Sse41.RoundToZero(firstOp);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var result = Sse41.RoundToZero(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse.LoadVector128((Single*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundToZero(firstOp);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundToZero(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse.LoadAlignedVector128((Single*)(_dataTable.inArrayPtr));
- var result = Sse41.RoundToZero(firstOp);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var result = Sse41.RoundToZero(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__RoundToZeroSingle();
- var result = Sse41.RoundToZero(test._fld);
+ var result = Sse41.RoundToZero(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__RoundToZeroSingle();
+
+ fixed (Vector128<Single>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.RoundToZero(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.RoundToZero(_fld);
+ var result = Sse41.RoundToZero(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Single>* pFld1 = &_fld1)
+ {
+ var result = Sse41.RoundToZero(
+ Sse.LoadVector128((Single*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.RoundToZero(test._fld);
+ var result = Sse41.RoundToZero(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.RoundToZero(
+ Sse.LoadVector128((Single*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Single[] inArray = new Single[Op1ElementCount];
+ Single[] inArray1 = new Single[Op1ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Single[] firstOp, Single[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.RoundToZero)}<Single>(Vector128<Single>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZeroScalar.Double.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZeroScalar.Double.cs
index 6314554c64..871cee1c38 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZeroScalar.Double.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZeroScalar.Double.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__RoundToZeroScalarDouble
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Double[] inArray1, Double[] inArray2, Double[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Double>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Double>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Double>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Double, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Double, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Double> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Double> _fld1;
private Vector128<Double> _fld2;
- private SimpleBinaryOpTest__DataTable<Double, Double, Double> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__RoundToZeroScalarDouble()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetDouble(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetDouble(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Double, Double, Double>(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Double[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
- var result = Sse41.RoundToZeroScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Double>>(_dataTable.inArray2Ptr);
+ var result = Sse41.RoundToZeroScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundToZeroScalar(left, right);
+ var op1 = Sse2.LoadVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundToZeroScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundToZeroScalar(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Double*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundToZeroScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Double> left, Vector128<Double> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Double> op1, Vector128<Double> op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Double[] inArray1 = new Double[Op1ElementCount];
Double[] inArray2 = new Double[Op2ElementCount];
Double[] outArray = new Double[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Double>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Double>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Double>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Double, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Double>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZeroScalar.Single.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZeroScalar.Single.cs
index e0ddc6348b..8dcf8169dc 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZeroScalar.Single.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/RoundToZeroScalar.Single.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__RoundToZeroScalarSingle
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Single[] inArray1, Single[] inArray2, Single[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Single>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Single>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Single>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Single, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Single, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Single> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Single> _fld1;
private Vector128<Single> _fld2;
- private SimpleBinaryOpTest__DataTable<Single, Single, Single> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__RoundToZeroScalarSingle()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSingle(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSingle(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Single, Single, Single>(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Single[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
- var result = Sse41.RoundToZeroScalar(left, right);
+ var op1 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Single>>(_dataTable.inArray2Ptr);
+ var result = Sse41.RoundToZeroScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundToZeroScalar(left, right);
+ var op1 = Sse.LoadVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundToZeroScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
- var right = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
- var result = Sse41.RoundToZeroScalar(left, right);
+ var op1 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray1Ptr));
+ var op2 = Sse.LoadAlignedVector128((Single*)(_dataTable.inArray2Ptr));
+ var result = Sse41.RoundToZeroScalar(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Single> left, Vector128<Single> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Single> op1, Vector128<Single> op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Single[] inArray1 = new Single[Op1ElementCount];
Single[] inArray2 = new Single[Op2ElementCount];
Single[] outArray = new Single[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Single>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Single>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Single>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Single, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Single>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Sse41_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Sse41_r.csproj
index c88f905b66..ea7c0f27dc 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Sse41_r.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Sse41_r.csproj
@@ -155,14 +155,9 @@
<Compile Include="Insert.Single.129.cs" />
<Compile Include="Insert.Single.192.cs" />
<Compile Include="Program.Sse41.cs" />
- <Compile Include="..\Shared\BooleanUnOpTest_DataTable.cs" />
- <Compile Include="..\Shared\BooleanBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\BooleanTwoCmpOpTest_DataTable.cs" />
- <Compile Include="..\Shared\HorizontalBinOpTest_DataTable.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Sse41_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Sse41_ro.csproj
index 8588e655d2..67552f99db 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Sse41_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/Sse41_ro.csproj
@@ -155,14 +155,9 @@
<Compile Include="Insert.Single.129.cs" />
<Compile Include="Insert.Single.192.cs" />
<Compile Include="Program.Sse41.cs" />
- <Compile Include="..\Shared\BooleanUnOpTest_DataTable.cs" />
- <Compile Include="..\Shared\BooleanBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\BooleanTwoCmpOpTest_DataTable.cs" />
- <Compile Include="..\Shared\HorizontalBinOpTest_DataTable.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
+ <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Byte.cs
index 0ccc97683e..971052bcb4 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Byte.cs
@@ -10,7 +10,6 @@
******************************************************************************/
using System;
-using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
@@ -53,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -68,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -92,24 +121,74 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanUnaryOpTest__TestAllOnesByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+
+ private GCHandle inHandle1;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Byte> _fld;
+ public Vector128<Byte> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref testStruct._fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
return testStruct;
}
public void RunStructFldScenario(BooleanUnaryOpTest__TestAllOnesByte testClass)
{
- var result = Sse41.TestAllOnes(_fld);
- testClass.ValidateResult(_fld, result);
+ var result = Sse41.TestAllOnes(_fld1);
+ testClass.ValidateResult(_fld1, result);
+ }
+
+ public void RunStructFldScenario_Load(BooleanUnaryOpTest__TestAllOnesByte testClass)
+ {
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Byte*)(pFld1))
+ );
+
+ testClass.ValidateResult(_fld1, result);
+ }
}
}
@@ -117,29 +196,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
- private static Byte[] _data = new Byte[Op1ElementCount];
+ private static Byte[] _data1 = new Byte[Op1ElementCount];
- private static Vector128<Byte> _clsVar;
+ private static Vector128<Byte> _clsVar1;
- private Vector128<Byte> _fld;
+ private Vector128<Byte> _fld1;
- private BooleanUnaryOpTest__DataTable<Byte> _dataTable;
+ private DataTable _dataTable;
static BooleanUnaryOpTest__TestAllOnesByte()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
}
public BooleanUnaryOpTest__TestAllOnesByte()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld), ref Unsafe.As<Byte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _fld1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new BooleanUnaryOpTest__DataTable<Byte>(_data, LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
+ _dataTable = new DataTable(_data1, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -151,10 +230,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.TestAllOnes(
- Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr)
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_Load()
@@ -162,10 +241,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.TestAllOnes(
- Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_LoadAligned()
@@ -173,10 +252,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.TestAllOnes(
- Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunReflectionScenario_UnsafeRead()
@@ -185,10 +264,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<Byte>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr)
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
@@ -197,10 +276,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<Byte>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
@@ -209,10 +288,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<Byte>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -220,40 +299,54 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.TestAllOnes(
- _clsVar
+ _clsVar1
);
- ValidateResult(_clsVar, result);
+ ValidateResult(_clsVar1, result);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Byte>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Byte*)(pClsVar1))
+ );
+
+ ValidateResult(_clsVar1, result);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var value = Unsafe.Read<Vector128<Byte>>(_dataTable.inArrayPtr);
- var result = Sse41.TestAllOnes(value);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var value = Sse2.LoadVector128((Byte*)(_dataTable.inArrayPtr));
- var result = Sse41.TestAllOnes(value);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var value = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArrayPtr));
- var result = Sse41.TestAllOnes(value);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunClassLclFldScenario()
@@ -261,18 +354,48 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new BooleanUnaryOpTest__TestAllOnesByte();
- var result = Sse41.TestAllOnes(test._fld);
+ var result = Sse41.TestAllOnes(test._fld1);
- ValidateResult(test._fld, result);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanUnaryOpTest__TestAllOnesByte();
+
+ fixed (Vector128<Byte>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Byte*)(pFld1))
+ );
+
+ ValidateResult(test._fld1, result);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.TestAllOnes(_fld);
+ var result = Sse41.TestAllOnes(_fld1);
- ValidateResult(_fld, result);
+ ValidateResult(_fld1, result);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Byte*)(pFld1))
+ );
+
+ ValidateResult(_fld1, result);
+ }
}
public void RunStructLclFldScenario()
@@ -280,8 +403,20 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.TestAllOnes(test._fld);
- ValidateResult(test._fld, result);
+ var result = Sse41.TestAllOnes(test._fld1);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Byte*)(&test._fld1))
+ );
+
+ ValidateResult(test._fld1, result);
}
public void RunStructFldScenario()
@@ -292,6 +427,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -313,26 +456,28 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> value, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, bool result, [CallerMemberName] string method = "")
{
- Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] inArray1 = new Byte[Op1ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), value);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
- ValidateResult(inArray, result, method);
+ ValidateResult(inArray1, result, method);
}
- private void ValidateResult(void* value, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, bool result, [CallerMemberName] string method = "")
{
- Byte[] inArray = new Byte[Op1ElementCount];
+ Byte[] inArray1 = new Byte[Op1ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(value), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- ValidateResult(inArray, result, method);
+ ValidateResult(inArray1, result, method);
}
private void ValidateResult(Byte[] value, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -340,11 +485,13 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~value[i] & byte.MaxValue) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestAllOnes)}<Byte>(Vector128<Byte>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Int16.cs
index a66141260f..dcb8dd6379 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Int16.cs
@@ -10,7 +10,6 @@
******************************************************************************/
using System;
-using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
@@ -53,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -68,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -92,24 +121,74 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanUnaryOpTest__TestAllOnesInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+
+ private GCHandle inHandle1;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Int16> _fld;
+ public Vector128<Int16> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld), ref Unsafe.As<Int16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
return testStruct;
}
public void RunStructFldScenario(BooleanUnaryOpTest__TestAllOnesInt16 testClass)
{
- var result = Sse41.TestAllOnes(_fld);
- testClass.ValidateResult(_fld, result);
+ var result = Sse41.TestAllOnes(_fld1);
+ testClass.ValidateResult(_fld1, result);
+ }
+
+ public void RunStructFldScenario_Load(BooleanUnaryOpTest__TestAllOnesInt16 testClass)
+ {
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Int16*)(pFld1))
+ );
+
+ testClass.ValidateResult(_fld1, result);
+ }
}
}
@@ -117,29 +196,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int16>>() / sizeof(Int16);
- private static Int16[] _data = new Int16[Op1ElementCount];
+ private static Int16[] _data1 = new Int16[Op1ElementCount];
- private static Vector128<Int16> _clsVar;
+ private static Vector128<Int16> _clsVar1;
- private Vector128<Int16> _fld;
+ private Vector128<Int16> _fld1;
- private BooleanUnaryOpTest__DataTable<Int16> _dataTable;
+ private DataTable _dataTable;
static BooleanUnaryOpTest__TestAllOnesInt16()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
}
public BooleanUnaryOpTest__TestAllOnesInt16()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new BooleanUnaryOpTest__DataTable<Int16>(_data, LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+ _dataTable = new DataTable(_data1, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -151,10 +230,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.TestAllOnes(
- Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr)
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_Load()
@@ -162,10 +241,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.TestAllOnes(
- Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_LoadAligned()
@@ -173,10 +252,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.TestAllOnes(
- Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunReflectionScenario_UnsafeRead()
@@ -185,10 +264,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<Int16>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr)
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
@@ -197,10 +276,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<Int16>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
@@ -209,10 +288,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<Int16>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -220,40 +299,54 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.TestAllOnes(
- _clsVar
+ _clsVar1
);
- ValidateResult(_clsVar, result);
+ ValidateResult(_clsVar1, result);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int16>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Int16*)(pClsVar1))
+ );
+
+ ValidateResult(_clsVar1, result);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var value = Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr);
- var result = Sse41.TestAllOnes(value);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var value = Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr));
- var result = Sse41.TestAllOnes(value);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var value = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr));
- var result = Sse41.TestAllOnes(value);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunClassLclFldScenario()
@@ -261,18 +354,48 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new BooleanUnaryOpTest__TestAllOnesInt16();
- var result = Sse41.TestAllOnes(test._fld);
+ var result = Sse41.TestAllOnes(test._fld1);
- ValidateResult(test._fld, result);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanUnaryOpTest__TestAllOnesInt16();
+
+ fixed (Vector128<Int16>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Int16*)(pFld1))
+ );
+
+ ValidateResult(test._fld1, result);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.TestAllOnes(_fld);
+ var result = Sse41.TestAllOnes(_fld1);
- ValidateResult(_fld, result);
+ ValidateResult(_fld1, result);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Int16*)(pFld1))
+ );
+
+ ValidateResult(_fld1, result);
+ }
}
public void RunStructLclFldScenario()
@@ -280,8 +403,20 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.TestAllOnes(test._fld);
- ValidateResult(test._fld, result);
+ var result = Sse41.TestAllOnes(test._fld1);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Int16*)(&test._fld1))
+ );
+
+ ValidateResult(test._fld1, result);
}
public void RunStructFldScenario()
@@ -292,6 +427,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -313,26 +456,28 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> value, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, bool result, [CallerMemberName] string method = "")
{
- Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] inArray1 = new Int16[Op1ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), value);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
- ValidateResult(inArray, result, method);
+ ValidateResult(inArray1, result, method);
}
- private void ValidateResult(void* value, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, bool result, [CallerMemberName] string method = "")
{
- Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] inArray1 = new Int16[Op1ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(value), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- ValidateResult(inArray, result, method);
+ ValidateResult(inArray1, result, method);
}
private void ValidateResult(Int16[] value, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -340,11 +485,13 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~value[i] & -1) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestAllOnes)}<Int16>(Vector128<Int16>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Int32.cs
index c1f0c8579b..18b2a9f3f9 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Int32.cs
@@ -10,7 +10,6 @@
******************************************************************************/
using System;
-using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
@@ -53,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -68,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -92,24 +121,74 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanUnaryOpTest__TestAllOnesInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+
+ private GCHandle inHandle1;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Int32> _fld;
+ public Vector128<Int32> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref testStruct._fld), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref testStruct._fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
return testStruct;
}
public void RunStructFldScenario(BooleanUnaryOpTest__TestAllOnesInt32 testClass)
{
- var result = Sse41.TestAllOnes(_fld);
- testClass.ValidateResult(_fld, result);
+ var result = Sse41.TestAllOnes(_fld1);
+ testClass.ValidateResult(_fld1, result);
+ }
+
+ public void RunStructFldScenario_Load(BooleanUnaryOpTest__TestAllOnesInt32 testClass)
+ {
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Int32*)(pFld1))
+ );
+
+ testClass.ValidateResult(_fld1, result);
+ }
}
}
@@ -117,29 +196,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int32>>() / sizeof(Int32);
- private static Int32[] _data = new Int32[Op1ElementCount];
+ private static Int32[] _data1 = new Int32[Op1ElementCount];
- private static Vector128<Int32> _clsVar;
+ private static Vector128<Int32> _clsVar1;
- private Vector128<Int32> _fld;
+ private Vector128<Int32> _fld1;
- private BooleanUnaryOpTest__DataTable<Int32> _dataTable;
+ private DataTable _dataTable;
static BooleanUnaryOpTest__TestAllOnesInt32()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
}
public BooleanUnaryOpTest__TestAllOnesInt32()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new BooleanUnaryOpTest__DataTable<Int32>(_data, LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+ _dataTable = new DataTable(_data1, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -151,10 +230,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.TestAllOnes(
- Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr)
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_Load()
@@ -162,10 +241,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.TestAllOnes(
- Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_LoadAligned()
@@ -173,10 +252,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.TestAllOnes(
- Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunReflectionScenario_UnsafeRead()
@@ -185,10 +264,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<Int32>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr)
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
@@ -197,10 +276,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<Int32>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
@@ -209,10 +288,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<Int32>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -220,40 +299,54 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.TestAllOnes(
- _clsVar
+ _clsVar1
);
- ValidateResult(_clsVar, result);
+ ValidateResult(_clsVar1, result);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int32>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Int32*)(pClsVar1))
+ );
+
+ ValidateResult(_clsVar1, result);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var value = Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr);
- var result = Sse41.TestAllOnes(value);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var value = Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr));
- var result = Sse41.TestAllOnes(value);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var value = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr));
- var result = Sse41.TestAllOnes(value);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunClassLclFldScenario()
@@ -261,18 +354,48 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new BooleanUnaryOpTest__TestAllOnesInt32();
- var result = Sse41.TestAllOnes(test._fld);
+ var result = Sse41.TestAllOnes(test._fld1);
- ValidateResult(test._fld, result);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanUnaryOpTest__TestAllOnesInt32();
+
+ fixed (Vector128<Int32>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Int32*)(pFld1))
+ );
+
+ ValidateResult(test._fld1, result);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.TestAllOnes(_fld);
+ var result = Sse41.TestAllOnes(_fld1);
- ValidateResult(_fld, result);
+ ValidateResult(_fld1, result);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Int32*)(pFld1))
+ );
+
+ ValidateResult(_fld1, result);
+ }
}
public void RunStructLclFldScenario()
@@ -280,8 +403,20 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.TestAllOnes(test._fld);
- ValidateResult(test._fld, result);
+ var result = Sse41.TestAllOnes(test._fld1);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Int32*)(&test._fld1))
+ );
+
+ ValidateResult(test._fld1, result);
}
public void RunStructFldScenario()
@@ -292,6 +427,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -313,26 +456,28 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> value, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, bool result, [CallerMemberName] string method = "")
{
- Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] inArray1 = new Int32[Op1ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), value);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
- ValidateResult(inArray, result, method);
+ ValidateResult(inArray1, result, method);
}
- private void ValidateResult(void* value, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, bool result, [CallerMemberName] string method = "")
{
- Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] inArray1 = new Int32[Op1ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(value), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- ValidateResult(inArray, result, method);
+ ValidateResult(inArray1, result, method);
}
private void ValidateResult(Int32[] value, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -340,11 +485,13 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~value[i] & -1) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestAllOnes)}<Int32>(Vector128<Int32>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Int64.cs
index c617953898..8165661caf 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.Int64.cs
@@ -10,7 +10,6 @@
******************************************************************************/
using System;
-using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
@@ -53,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -68,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -92,24 +121,74 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanUnaryOpTest__TestAllOnesInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+
+ private GCHandle inHandle1;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Int64> _fld;
+ public Vector128<Int64> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld), ref Unsafe.As<Int64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref testStruct._fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
return testStruct;
}
public void RunStructFldScenario(BooleanUnaryOpTest__TestAllOnesInt64 testClass)
{
- var result = Sse41.TestAllOnes(_fld);
- testClass.ValidateResult(_fld, result);
+ var result = Sse41.TestAllOnes(_fld1);
+ testClass.ValidateResult(_fld1, result);
+ }
+
+ public void RunStructFldScenario_Load(BooleanUnaryOpTest__TestAllOnesInt64 testClass)
+ {
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Int64*)(pFld1))
+ );
+
+ testClass.ValidateResult(_fld1, result);
+ }
}
}
@@ -117,29 +196,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int64>>() / sizeof(Int64);
- private static Int64[] _data = new Int64[Op1ElementCount];
+ private static Int64[] _data1 = new Int64[Op1ElementCount];
- private static Vector128<Int64> _clsVar;
+ private static Vector128<Int64> _clsVar1;
- private Vector128<Int64> _fld;
+ private Vector128<Int64> _fld1;
- private BooleanUnaryOpTest__DataTable<Int64> _dataTable;
+ private DataTable _dataTable;
static BooleanUnaryOpTest__TestAllOnesInt64()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar), ref Unsafe.As<Int64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
}
public BooleanUnaryOpTest__TestAllOnesInt64()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld), ref Unsafe.As<Int64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _fld1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new BooleanUnaryOpTest__DataTable<Int64>(_data, LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
+ _dataTable = new DataTable(_data1, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -151,10 +230,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.TestAllOnes(
- Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr)
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_Load()
@@ -162,10 +241,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.TestAllOnes(
- Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_LoadAligned()
@@ -173,10 +252,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.TestAllOnes(
- Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunReflectionScenario_UnsafeRead()
@@ -185,10 +264,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<Int64>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr)
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
@@ -197,10 +276,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<Int64>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
@@ -209,10 +288,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<Int64>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -220,40 +299,54 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.TestAllOnes(
- _clsVar
+ _clsVar1
);
- ValidateResult(_clsVar, result);
+ ValidateResult(_clsVar1, result);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int64>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Int64*)(pClsVar1))
+ );
+
+ ValidateResult(_clsVar1, result);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var value = Unsafe.Read<Vector128<Int64>>(_dataTable.inArrayPtr);
- var result = Sse41.TestAllOnes(value);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var value = Sse2.LoadVector128((Int64*)(_dataTable.inArrayPtr));
- var result = Sse41.TestAllOnes(value);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var value = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArrayPtr));
- var result = Sse41.TestAllOnes(value);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunClassLclFldScenario()
@@ -261,18 +354,48 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new BooleanUnaryOpTest__TestAllOnesInt64();
- var result = Sse41.TestAllOnes(test._fld);
+ var result = Sse41.TestAllOnes(test._fld1);
- ValidateResult(test._fld, result);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanUnaryOpTest__TestAllOnesInt64();
+
+ fixed (Vector128<Int64>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Int64*)(pFld1))
+ );
+
+ ValidateResult(test._fld1, result);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.TestAllOnes(_fld);
+ var result = Sse41.TestAllOnes(_fld1);
- ValidateResult(_fld, result);
+ ValidateResult(_fld1, result);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Int64*)(pFld1))
+ );
+
+ ValidateResult(_fld1, result);
+ }
}
public void RunStructLclFldScenario()
@@ -280,8 +403,20 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.TestAllOnes(test._fld);
- ValidateResult(test._fld, result);
+ var result = Sse41.TestAllOnes(test._fld1);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((Int64*)(&test._fld1))
+ );
+
+ ValidateResult(test._fld1, result);
}
public void RunStructFldScenario()
@@ -292,6 +427,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -313,26 +456,28 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> value, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, bool result, [CallerMemberName] string method = "")
{
- Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] inArray1 = new Int64[Op1ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), value);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
- ValidateResult(inArray, result, method);
+ ValidateResult(inArray1, result, method);
}
- private void ValidateResult(void* value, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, bool result, [CallerMemberName] string method = "")
{
- Int64[] inArray = new Int64[Op1ElementCount];
+ Int64[] inArray1 = new Int64[Op1ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(value), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- ValidateResult(inArray, result, method);
+ ValidateResult(inArray1, result, method);
}
private void ValidateResult(Int64[] value, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -340,11 +485,13 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~value[i] & -1) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestAllOnes)}<Int64>(Vector128<Int64>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.SByte.cs
index 19b3f4318f..a0c103d9c8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.SByte.cs
@@ -10,7 +10,6 @@
******************************************************************************/
using System;
-using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
@@ -53,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -68,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -92,24 +121,74 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanUnaryOpTest__TestAllOnesSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+
+ private GCHandle inHandle1;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<SByte> _fld;
+ public Vector128<SByte> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
return testStruct;
}
public void RunStructFldScenario(BooleanUnaryOpTest__TestAllOnesSByte testClass)
{
- var result = Sse41.TestAllOnes(_fld);
- testClass.ValidateResult(_fld, result);
+ var result = Sse41.TestAllOnes(_fld1);
+ testClass.ValidateResult(_fld1, result);
+ }
+
+ public void RunStructFldScenario_Load(BooleanUnaryOpTest__TestAllOnesSByte testClass)
+ {
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((SByte*)(pFld1))
+ );
+
+ testClass.ValidateResult(_fld1, result);
+ }
}
}
@@ -117,29 +196,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
- private static SByte[] _data = new SByte[Op1ElementCount];
+ private static SByte[] _data1 = new SByte[Op1ElementCount];
- private static Vector128<SByte> _clsVar;
+ private static Vector128<SByte> _clsVar1;
- private Vector128<SByte> _fld;
+ private Vector128<SByte> _fld1;
- private BooleanUnaryOpTest__DataTable<SByte> _dataTable;
+ private DataTable _dataTable;
static BooleanUnaryOpTest__TestAllOnesSByte()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
}
public BooleanUnaryOpTest__TestAllOnesSByte()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new BooleanUnaryOpTest__DataTable<SByte>(_data, LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+ _dataTable = new DataTable(_data1, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -151,10 +230,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.TestAllOnes(
- Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr)
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_Load()
@@ -162,10 +241,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.TestAllOnes(
- Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_LoadAligned()
@@ -173,10 +252,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.TestAllOnes(
- Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunReflectionScenario_UnsafeRead()
@@ -185,10 +264,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr)
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
@@ -197,10 +276,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
@@ -209,10 +288,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -220,40 +299,54 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.TestAllOnes(
- _clsVar
+ _clsVar1
);
- ValidateResult(_clsVar, result);
+ ValidateResult(_clsVar1, result);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<SByte>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((SByte*)(pClsVar1))
+ );
+
+ ValidateResult(_clsVar1, result);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var value = Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr);
- var result = Sse41.TestAllOnes(value);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var value = Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr));
- var result = Sse41.TestAllOnes(value);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var value = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr));
- var result = Sse41.TestAllOnes(value);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunClassLclFldScenario()
@@ -261,18 +354,48 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new BooleanUnaryOpTest__TestAllOnesSByte();
- var result = Sse41.TestAllOnes(test._fld);
+ var result = Sse41.TestAllOnes(test._fld1);
- ValidateResult(test._fld, result);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanUnaryOpTest__TestAllOnesSByte();
+
+ fixed (Vector128<SByte>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((SByte*)(pFld1))
+ );
+
+ ValidateResult(test._fld1, result);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.TestAllOnes(_fld);
+ var result = Sse41.TestAllOnes(_fld1);
- ValidateResult(_fld, result);
+ ValidateResult(_fld1, result);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((SByte*)(pFld1))
+ );
+
+ ValidateResult(_fld1, result);
+ }
}
public void RunStructLclFldScenario()
@@ -280,8 +403,20 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.TestAllOnes(test._fld);
- ValidateResult(test._fld, result);
+ var result = Sse41.TestAllOnes(test._fld1);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((SByte*)(&test._fld1))
+ );
+
+ ValidateResult(test._fld1, result);
}
public void RunStructFldScenario()
@@ -292,6 +427,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -313,26 +456,28 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> value, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, bool result, [CallerMemberName] string method = "")
{
- SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] inArray1 = new SByte[Op1ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), value);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
- ValidateResult(inArray, result, method);
+ ValidateResult(inArray1, result, method);
}
- private void ValidateResult(void* value, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, bool result, [CallerMemberName] string method = "")
{
- SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] inArray1 = new SByte[Op1ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(value), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- ValidateResult(inArray, result, method);
+ ValidateResult(inArray1, result, method);
}
private void ValidateResult(SByte[] value, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -340,11 +485,13 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~value[i] & -1) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestAllOnes)}<SByte>(Vector128<SByte>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.UInt16.cs
index 6bb530abcb..a845f0695d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.UInt16.cs
@@ -10,7 +10,6 @@
******************************************************************************/
using System;
-using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
@@ -53,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -68,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -92,24 +121,74 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanUnaryOpTest__TestAllOnesUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+
+ private GCHandle inHandle1;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<UInt16> _fld;
+ public Vector128<UInt16> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref testStruct._fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
return testStruct;
}
public void RunStructFldScenario(BooleanUnaryOpTest__TestAllOnesUInt16 testClass)
{
- var result = Sse41.TestAllOnes(_fld);
- testClass.ValidateResult(_fld, result);
+ var result = Sse41.TestAllOnes(_fld1);
+ testClass.ValidateResult(_fld1, result);
+ }
+
+ public void RunStructFldScenario_Load(BooleanUnaryOpTest__TestAllOnesUInt16 testClass)
+ {
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((UInt16*)(pFld1))
+ );
+
+ testClass.ValidateResult(_fld1, result);
+ }
}
}
@@ -117,29 +196,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<UInt16>>() / sizeof(UInt16);
- private static UInt16[] _data = new UInt16[Op1ElementCount];
+ private static UInt16[] _data1 = new UInt16[Op1ElementCount];
- private static Vector128<UInt16> _clsVar;
+ private static Vector128<UInt16> _clsVar1;
- private Vector128<UInt16> _fld;
+ private Vector128<UInt16> _fld1;
- private BooleanUnaryOpTest__DataTable<UInt16> _dataTable;
+ private DataTable _dataTable;
static BooleanUnaryOpTest__TestAllOnesUInt16()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar), ref Unsafe.As<UInt16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
}
public BooleanUnaryOpTest__TestAllOnesUInt16()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld), ref Unsafe.As<UInt16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _fld1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new BooleanUnaryOpTest__DataTable<UInt16>(_data, LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
+ _dataTable = new DataTable(_data1, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -151,10 +230,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.TestAllOnes(
- Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr)
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_Load()
@@ -162,10 +241,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.TestAllOnes(
- Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_LoadAligned()
@@ -173,10 +252,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.TestAllOnes(
- Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunReflectionScenario_UnsafeRead()
@@ -185,10 +264,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<UInt16>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr)
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
@@ -197,10 +276,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<UInt16>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
@@ -209,10 +288,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<UInt16>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -220,40 +299,54 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.TestAllOnes(
- _clsVar
+ _clsVar1
);
- ValidateResult(_clsVar, result);
+ ValidateResult(_clsVar1, result);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt16>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((UInt16*)(pClsVar1))
+ );
+
+ ValidateResult(_clsVar1, result);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var value = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArrayPtr);
- var result = Sse41.TestAllOnes(value);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var value = Sse2.LoadVector128((UInt16*)(_dataTable.inArrayPtr));
- var result = Sse41.TestAllOnes(value);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var value = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArrayPtr));
- var result = Sse41.TestAllOnes(value);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunClassLclFldScenario()
@@ -261,18 +354,48 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new BooleanUnaryOpTest__TestAllOnesUInt16();
- var result = Sse41.TestAllOnes(test._fld);
+ var result = Sse41.TestAllOnes(test._fld1);
- ValidateResult(test._fld, result);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanUnaryOpTest__TestAllOnesUInt16();
+
+ fixed (Vector128<UInt16>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((UInt16*)(pFld1))
+ );
+
+ ValidateResult(test._fld1, result);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.TestAllOnes(_fld);
+ var result = Sse41.TestAllOnes(_fld1);
- ValidateResult(_fld, result);
+ ValidateResult(_fld1, result);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((UInt16*)(pFld1))
+ );
+
+ ValidateResult(_fld1, result);
+ }
}
public void RunStructLclFldScenario()
@@ -280,8 +403,20 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.TestAllOnes(test._fld);
- ValidateResult(test._fld, result);
+ var result = Sse41.TestAllOnes(test._fld1);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((UInt16*)(&test._fld1))
+ );
+
+ ValidateResult(test._fld1, result);
}
public void RunStructFldScenario()
@@ -292,6 +427,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -313,26 +456,28 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> value, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, bool result, [CallerMemberName] string method = "")
{
- UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] inArray1 = new UInt16[Op1ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), value);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
- ValidateResult(inArray, result, method);
+ ValidateResult(inArray1, result, method);
}
- private void ValidateResult(void* value, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, bool result, [CallerMemberName] string method = "")
{
- UInt16[] inArray = new UInt16[Op1ElementCount];
+ UInt16[] inArray1 = new UInt16[Op1ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(value), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- ValidateResult(inArray, result, method);
+ ValidateResult(inArray1, result, method);
}
private void ValidateResult(UInt16[] value, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -340,11 +485,13 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~value[i] & ushort.MaxValue) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestAllOnes)}<UInt16>(Vector128<UInt16>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.UInt32.cs
index 08b3b8fbe8..5b9ff68578 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.UInt32.cs
@@ -10,7 +10,6 @@
******************************************************************************/
using System;
-using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
@@ -53,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -68,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -92,24 +121,74 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanUnaryOpTest__TestAllOnesUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+
+ private GCHandle inHandle1;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<UInt32> _fld;
+ public Vector128<UInt32> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref testStruct._fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
return testStruct;
}
public void RunStructFldScenario(BooleanUnaryOpTest__TestAllOnesUInt32 testClass)
{
- var result = Sse41.TestAllOnes(_fld);
- testClass.ValidateResult(_fld, result);
+ var result = Sse41.TestAllOnes(_fld1);
+ testClass.ValidateResult(_fld1, result);
+ }
+
+ public void RunStructFldScenario_Load(BooleanUnaryOpTest__TestAllOnesUInt32 testClass)
+ {
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((UInt32*)(pFld1))
+ );
+
+ testClass.ValidateResult(_fld1, result);
+ }
}
}
@@ -117,29 +196,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<UInt32>>() / sizeof(UInt32);
- private static UInt32[] _data = new UInt32[Op1ElementCount];
+ private static UInt32[] _data1 = new UInt32[Op1ElementCount];
- private static Vector128<UInt32> _clsVar;
+ private static Vector128<UInt32> _clsVar1;
- private Vector128<UInt32> _fld;
+ private Vector128<UInt32> _fld1;
- private BooleanUnaryOpTest__DataTable<UInt32> _dataTable;
+ private DataTable _dataTable;
static BooleanUnaryOpTest__TestAllOnesUInt32()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar), ref Unsafe.As<UInt32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
}
public BooleanUnaryOpTest__TestAllOnesUInt32()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld), ref Unsafe.As<UInt32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _fld1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new BooleanUnaryOpTest__DataTable<UInt32>(_data, LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
+ _dataTable = new DataTable(_data1, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -151,10 +230,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.TestAllOnes(
- Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr)
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_Load()
@@ -162,10 +241,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.TestAllOnes(
- Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_LoadAligned()
@@ -173,10 +252,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.TestAllOnes(
- Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunReflectionScenario_UnsafeRead()
@@ -185,10 +264,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<UInt32>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr)
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
@@ -197,10 +276,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<UInt32>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
@@ -209,10 +288,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<UInt32>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -220,40 +299,54 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.TestAllOnes(
- _clsVar
+ _clsVar1
);
- ValidateResult(_clsVar, result);
+ ValidateResult(_clsVar1, result);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt32>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((UInt32*)(pClsVar1))
+ );
+
+ ValidateResult(_clsVar1, result);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var value = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArrayPtr);
- var result = Sse41.TestAllOnes(value);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var value = Sse2.LoadVector128((UInt32*)(_dataTable.inArrayPtr));
- var result = Sse41.TestAllOnes(value);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var value = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArrayPtr));
- var result = Sse41.TestAllOnes(value);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunClassLclFldScenario()
@@ -261,18 +354,48 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new BooleanUnaryOpTest__TestAllOnesUInt32();
- var result = Sse41.TestAllOnes(test._fld);
+ var result = Sse41.TestAllOnes(test._fld1);
- ValidateResult(test._fld, result);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanUnaryOpTest__TestAllOnesUInt32();
+
+ fixed (Vector128<UInt32>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((UInt32*)(pFld1))
+ );
+
+ ValidateResult(test._fld1, result);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.TestAllOnes(_fld);
+ var result = Sse41.TestAllOnes(_fld1);
- ValidateResult(_fld, result);
+ ValidateResult(_fld1, result);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((UInt32*)(pFld1))
+ );
+
+ ValidateResult(_fld1, result);
+ }
}
public void RunStructLclFldScenario()
@@ -280,8 +403,20 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.TestAllOnes(test._fld);
- ValidateResult(test._fld, result);
+ var result = Sse41.TestAllOnes(test._fld1);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((UInt32*)(&test._fld1))
+ );
+
+ ValidateResult(test._fld1, result);
}
public void RunStructFldScenario()
@@ -292,6 +427,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -313,26 +456,28 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> value, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, bool result, [CallerMemberName] string method = "")
{
- UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] inArray1 = new UInt32[Op1ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), value);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
- ValidateResult(inArray, result, method);
+ ValidateResult(inArray1, result, method);
}
- private void ValidateResult(void* value, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, bool result, [CallerMemberName] string method = "")
{
- UInt32[] inArray = new UInt32[Op1ElementCount];
+ UInt32[] inArray1 = new UInt32[Op1ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(value), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- ValidateResult(inArray, result, method);
+ ValidateResult(inArray1, result, method);
}
private void ValidateResult(UInt32[] value, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -340,11 +485,13 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~value[i] & uint.MaxValue) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestAllOnes)}<UInt32>(Vector128<UInt32>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.UInt64.cs
index 13c9588541..b20108f761 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllOnes.UInt64.cs
@@ -10,7 +10,6 @@
******************************************************************************/
using System;
-using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics;
@@ -53,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -68,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -92,24 +121,74 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanUnaryOpTest__TestAllOnesUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+
+ private GCHandle inHandle1;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<UInt64> _fld;
+ public Vector128<UInt64> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref testStruct._fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
return testStruct;
}
public void RunStructFldScenario(BooleanUnaryOpTest__TestAllOnesUInt64 testClass)
{
- var result = Sse41.TestAllOnes(_fld);
- testClass.ValidateResult(_fld, result);
+ var result = Sse41.TestAllOnes(_fld1);
+ testClass.ValidateResult(_fld1, result);
+ }
+
+ public void RunStructFldScenario_Load(BooleanUnaryOpTest__TestAllOnesUInt64 testClass)
+ {
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((UInt64*)(pFld1))
+ );
+
+ testClass.ValidateResult(_fld1, result);
+ }
}
}
@@ -117,29 +196,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<UInt64>>() / sizeof(UInt64);
- private static UInt64[] _data = new UInt64[Op1ElementCount];
+ private static UInt64[] _data1 = new UInt64[Op1ElementCount];
- private static Vector128<UInt64> _clsVar;
+ private static Vector128<UInt64> _clsVar1;
- private Vector128<UInt64> _fld;
+ private Vector128<UInt64> _fld1;
- private BooleanUnaryOpTest__DataTable<UInt64> _dataTable;
+ private DataTable _dataTable;
static BooleanUnaryOpTest__TestAllOnesUInt64()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar), ref Unsafe.As<UInt64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
}
public BooleanUnaryOpTest__TestAllOnesUInt64()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld), ref Unsafe.As<UInt64, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _fld1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new BooleanUnaryOpTest__DataTable<UInt64>(_data, LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
+ _dataTable = new DataTable(_data1, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -151,10 +230,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Sse41.TestAllOnes(
- Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr)
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_Load()
@@ -162,10 +241,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Sse41.TestAllOnes(
- Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunBasicScenario_LoadAligned()
@@ -173,10 +252,10 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Sse41.TestAllOnes(
- Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr))
);
- ValidateResult(_dataTable.inArrayPtr, result);
+ ValidateResult(_dataTable.inArray1Ptr, result);
}
public void RunReflectionScenario_UnsafeRead()
@@ -185,10 +264,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<UInt64>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr)
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
@@ -197,10 +276,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<UInt64>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
@@ -209,10 +288,10 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllOnes), new Type[] { typeof(Vector128<UInt64>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr))
});
- ValidateResult(_dataTable.inArrayPtr, (bool)(result));
+ ValidateResult(_dataTable.inArray1Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -220,40 +299,54 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Sse41.TestAllOnes(
- _clsVar
+ _clsVar1
);
- ValidateResult(_clsVar, result);
+ ValidateResult(_clsVar1, result);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt64>* pClsVar1 = &_clsVar1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((UInt64*)(pClsVar1))
+ );
+
+ ValidateResult(_clsVar1, result);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var value = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArrayPtr);
- var result = Sse41.TestAllOnes(value);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var value = Sse2.LoadVector128((UInt64*)(_dataTable.inArrayPtr));
- var result = Sse41.TestAllOnes(value);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var value = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArrayPtr));
- var result = Sse41.TestAllOnes(value);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var result = Sse41.TestAllOnes(op1);
- ValidateResult(value, result);
+ ValidateResult(op1, result);
}
public void RunClassLclFldScenario()
@@ -261,18 +354,48 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new BooleanUnaryOpTest__TestAllOnesUInt64();
- var result = Sse41.TestAllOnes(test._fld);
+ var result = Sse41.TestAllOnes(test._fld1);
- ValidateResult(test._fld, result);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanUnaryOpTest__TestAllOnesUInt64();
+
+ fixed (Vector128<UInt64>* pFld1 = &test._fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((UInt64*)(pFld1))
+ );
+
+ ValidateResult(test._fld1, result);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Sse41.TestAllOnes(_fld);
+ var result = Sse41.TestAllOnes(_fld1);
- ValidateResult(_fld, result);
+ ValidateResult(_fld1, result);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ {
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((UInt64*)(pFld1))
+ );
+
+ ValidateResult(_fld1, result);
+ }
}
public void RunStructLclFldScenario()
@@ -280,8 +403,20 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Sse41.TestAllOnes(test._fld);
- ValidateResult(test._fld, result);
+ var result = Sse41.TestAllOnes(test._fld1);
+ ValidateResult(test._fld1, result);
+ }
+
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestAllOnes(
+ Sse2.LoadVector128((UInt64*)(&test._fld1))
+ );
+
+ ValidateResult(test._fld1, result);
}
public void RunStructFldScenario()
@@ -292,6 +427,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -313,26 +456,28 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> value, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, bool result, [CallerMemberName] string method = "")
{
- UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] inArray1 = new UInt64[Op1ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), value);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
- ValidateResult(inArray, result, method);
+ ValidateResult(inArray1, result, method);
}
- private void ValidateResult(void* value, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, bool result, [CallerMemberName] string method = "")
{
- UInt64[] inArray = new UInt64[Op1ElementCount];
+ UInt64[] inArray1 = new UInt64[Op1ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(value), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- ValidateResult(inArray, result, method);
+ ValidateResult(inArray1, result, method);
}
private void ValidateResult(UInt64[] value, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -340,11 +485,13 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~value[i] & ulong.MaxValue) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestAllOnes)}<UInt64>(Vector128<UInt64>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" value: ({string.Join(", ", value)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Byte.cs
index 14e95b2a28..074374d3f4 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Byte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestAllZerosByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestAllZeros(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestAllZerosByte testClass)
+ {
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ fixed (Vector128<Byte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private BooleanBinaryOpTest__DataTable<Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestAllZerosByte()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Byte, Byte>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Byte>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Byte>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Byte*)(pClsVar1)),
+ Sse2.LoadVector128((Byte*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestAllZerosByte();
+
+ fixed (Vector128<Byte>* pFld1 = &test._fld1)
+ fixed (Vector128<Byte>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ fixed (Vector128<Byte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Byte*)(&test._fld1)),
+ Sse2.LoadVector128((Byte*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, bool result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Byte[] left, Byte[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestAllZeros)}<Byte>(Vector128<Byte>, Vector128<Byte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Int16.cs
index 1617e451e0..a817f88263 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Int16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestAllZerosInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestAllZeros(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestAllZerosInt16 testClass)
+ {
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private BooleanBinaryOpTest__DataTable<Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestAllZerosInt16()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Int16, Int16>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int16>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Int16*)(pClsVar1)),
+ Sse2.LoadVector128((Int16*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestAllZerosInt16();
+
+ fixed (Vector128<Int16>* pFld1 = &test._fld1)
+ fixed (Vector128<Int16>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Int16*)(&test._fld1)),
+ Sse2.LoadVector128((Int16*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, bool result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int16[] left, Int16[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestAllZeros)}<Int16>(Vector128<Int16>, Vector128<Int16>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Int32.cs
index 0e88334334..b5fe2e0258 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Int32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestAllZerosInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestAllZeros(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestAllZerosInt32 testClass)
+ {
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private BooleanBinaryOpTest__DataTable<Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestAllZerosInt32()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Int32, Int32>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int32>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Int32*)(pClsVar1)),
+ Sse2.LoadVector128((Int32*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestAllZerosInt32();
+
+ fixed (Vector128<Int32>* pFld1 = &test._fld1)
+ fixed (Vector128<Int32>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Int32*)(&test._fld1)),
+ Sse2.LoadVector128((Int32*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, bool result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int32[] left, Int32[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestAllZeros)}<Int32>(Vector128<Int32>, Vector128<Int32>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Int64.cs
index fab4dcddf1..9668f1aaeb 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.Int64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestAllZerosInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int64> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestAllZeros(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestAllZerosInt64 testClass)
+ {
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ fixed (Vector128<Int64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int64> _fld1;
private Vector128<Int64> _fld2;
- private BooleanBinaryOpTest__DataTable<Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestAllZerosInt64()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Int64, Int64>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int64>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int64>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Int64*)(pClsVar1)),
+ Sse2.LoadVector128((Int64*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestAllZerosInt64();
+
+ fixed (Vector128<Int64>* pFld1 = &test._fld1)
+ fixed (Vector128<Int64>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ fixed (Vector128<Int64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((Int64*)(&test._fld1)),
+ Sse2.LoadVector128((Int64*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, Vector128<Int64> op2, bool result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int64[] left, Int64[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestAllZeros)}<Int64>(Vector128<Int64>, Vector128<Int64>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.SByte.cs
index e70a856c42..b9bac593fb 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.SByte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestAllZerosSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestAllZeros(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestAllZerosSByte testClass)
+ {
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ fixed (Vector128<SByte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private BooleanBinaryOpTest__DataTable<SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestAllZerosSByte()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<SByte, SByte>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<SByte>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<SByte>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((SByte*)(pClsVar1)),
+ Sse2.LoadVector128((SByte*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestAllZerosSByte();
+
+ fixed (Vector128<SByte>* pFld1 = &test._fld1)
+ fixed (Vector128<SByte>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ fixed (Vector128<SByte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((SByte*)(&test._fld1)),
+ Sse2.LoadVector128((SByte*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, bool result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(SByte[] left, SByte[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestAllZeros)}<SByte>(Vector128<SByte>, Vector128<SByte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.UInt16.cs
index 30c8b6924f..6fc7837d50 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.UInt16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestAllZerosUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestAllZeros(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestAllZerosUInt16 testClass)
+ {
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ fixed (Vector128<UInt16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private BooleanBinaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestAllZerosUInt16()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<UInt16, UInt16>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt16>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((UInt16*)(pClsVar1)),
+ Sse2.LoadVector128((UInt16*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestAllZerosUInt16();
+
+ fixed (Vector128<UInt16>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt16>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ fixed (Vector128<UInt16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((UInt16*)(&test._fld1)),
+ Sse2.LoadVector128((UInt16*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, bool result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt16[] left, UInt16[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestAllZeros)}<UInt16>(Vector128<UInt16>, Vector128<UInt16>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.UInt32.cs
index 4ea3530464..32d21b47ae 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.UInt32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestAllZerosUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestAllZeros(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestAllZerosUInt32 testClass)
+ {
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ fixed (Vector128<UInt32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private BooleanBinaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestAllZerosUInt32()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<UInt32, UInt32>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt32>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((UInt32*)(pClsVar1)),
+ Sse2.LoadVector128((UInt32*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestAllZerosUInt32();
+
+ fixed (Vector128<UInt32>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt32>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ fixed (Vector128<UInt32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((UInt32*)(&test._fld1)),
+ Sse2.LoadVector128((UInt32*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, bool result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt32[] left, UInt32[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestAllZeros)}<UInt32>(Vector128<UInt32>, Vector128<UInt32>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.UInt64.cs
index 83333a9baf..51dca4e987 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestAllZeros.UInt64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestAllZerosUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt64> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestAllZeros(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestAllZerosUInt64 testClass)
+ {
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ fixed (Vector128<UInt64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt64> _fld1;
private Vector128<UInt64> _fld2;
- private BooleanBinaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestAllZerosUInt64()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<UInt64, UInt64>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestAllZeros), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt64>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt64>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((UInt64*)(pClsVar1)),
+ Sse2.LoadVector128((UInt64*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestAllZeros(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestAllZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestAllZerosUInt64();
+
+ fixed (Vector128<UInt64>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt64>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ fixed (Vector128<UInt64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestAllZeros(
+ Sse2.LoadVector128((UInt64*)(&test._fld1)),
+ Sse2.LoadVector128((UInt64*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, Vector128<UInt64> op2, bool result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt64[] left, UInt64[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestAllZeros)}<UInt64>(Vector128<UInt64>, Vector128<UInt64>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Byte.cs
index ff20036f2c..fd7a963aaa 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Byte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestCByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestCByte testClass)
+ {
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ fixed (Vector128<Byte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private BooleanBinaryOpTest__DataTable<Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestCByte()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Byte, Byte>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Byte>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Byte>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Byte*)(pClsVar1)),
+ Sse2.LoadVector128((Byte*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestC(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestC(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestC(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestCByte();
+
+ fixed (Vector128<Byte>* pFld1 = &test._fld1)
+ fixed (Vector128<Byte>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ fixed (Vector128<Byte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Byte*)(&test._fld1)),
+ Sse2.LoadVector128((Byte*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, bool result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Byte[] left, Byte[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestC)}<Byte>(Vector128<Byte>, Vector128<Byte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Int16.cs
index 5ca469b11c..72fab4c734 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Int16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestCInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestCInt16 testClass)
+ {
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private BooleanBinaryOpTest__DataTable<Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestCInt16()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Int16, Int16>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int16>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Int16*)(pClsVar1)),
+ Sse2.LoadVector128((Int16*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestC(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestC(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestC(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestCInt16();
+
+ fixed (Vector128<Int16>* pFld1 = &test._fld1)
+ fixed (Vector128<Int16>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Int16*)(&test._fld1)),
+ Sse2.LoadVector128((Int16*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, bool result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int16[] left, Int16[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestC)}<Int16>(Vector128<Int16>, Vector128<Int16>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Int32.cs
index f1de8b6835..25fcda3874 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Int32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestCInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestCInt32 testClass)
+ {
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private BooleanBinaryOpTest__DataTable<Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestCInt32()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Int32, Int32>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int32>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Int32*)(pClsVar1)),
+ Sse2.LoadVector128((Int32*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestC(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestC(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestC(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestCInt32();
+
+ fixed (Vector128<Int32>* pFld1 = &test._fld1)
+ fixed (Vector128<Int32>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Int32*)(&test._fld1)),
+ Sse2.LoadVector128((Int32*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, bool result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int32[] left, Int32[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestC)}<Int32>(Vector128<Int32>, Vector128<Int32>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Int64.cs
index 5889454be5..f7815f5bff 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.Int64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestCInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int64> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestCInt64 testClass)
+ {
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ fixed (Vector128<Int64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int64> _fld1;
private Vector128<Int64> _fld2;
- private BooleanBinaryOpTest__DataTable<Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestCInt64()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Int64, Int64>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int64>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int64>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Int64*)(pClsVar1)),
+ Sse2.LoadVector128((Int64*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestC(left, right);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestC(left, right);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestC(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestCInt64();
+
+ fixed (Vector128<Int64>* pFld1 = &test._fld1)
+ fixed (Vector128<Int64>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ fixed (Vector128<Int64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((Int64*)(&test._fld1)),
+ Sse2.LoadVector128((Int64*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, Vector128<Int64> op2, bool result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int64[] left, Int64[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestC)}<Int64>(Vector128<Int64>, Vector128<Int64>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.SByte.cs
index a4342ba196..7a41ed3ed1 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.SByte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestCSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestCSByte testClass)
+ {
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ fixed (Vector128<SByte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private BooleanBinaryOpTest__DataTable<SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestCSByte()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<SByte, SByte>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<SByte>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<SByte>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((SByte*)(pClsVar1)),
+ Sse2.LoadVector128((SByte*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestC(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestC(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestC(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestCSByte();
+
+ fixed (Vector128<SByte>* pFld1 = &test._fld1)
+ fixed (Vector128<SByte>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ fixed (Vector128<SByte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((SByte*)(&test._fld1)),
+ Sse2.LoadVector128((SByte*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, bool result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(SByte[] left, SByte[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestC)}<SByte>(Vector128<SByte>, Vector128<SByte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.UInt16.cs
index 175c6567d1..038a904374 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.UInt16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestCUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestCUInt16 testClass)
+ {
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ fixed (Vector128<UInt16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private BooleanBinaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestCUInt16()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<UInt16, UInt16>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt16>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((UInt16*)(pClsVar1)),
+ Sse2.LoadVector128((UInt16*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestC(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestC(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestC(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestCUInt16();
+
+ fixed (Vector128<UInt16>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt16>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ fixed (Vector128<UInt16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((UInt16*)(&test._fld1)),
+ Sse2.LoadVector128((UInt16*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, bool result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt16[] left, UInt16[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestC)}<UInt16>(Vector128<UInt16>, Vector128<UInt16>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.UInt32.cs
index 162159b8c5..caa0243708 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.UInt32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestCUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestCUInt32 testClass)
+ {
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ fixed (Vector128<UInt32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private BooleanBinaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestCUInt32()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<UInt32, UInt32>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt32>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((UInt32*)(pClsVar1)),
+ Sse2.LoadVector128((UInt32*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestC(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestC(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestC(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestCUInt32();
+
+ fixed (Vector128<UInt32>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt32>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ fixed (Vector128<UInt32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((UInt32*)(&test._fld1)),
+ Sse2.LoadVector128((UInt32*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, bool result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt32[] left, UInt32[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestC)}<UInt32>(Vector128<UInt32>, Vector128<UInt32>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.UInt64.cs
index ade8dd8c6f..4384cac881 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestC.UInt64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestCUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt64> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestCUInt64 testClass)
+ {
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ fixed (Vector128<UInt64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt64> _fld1;
private Vector128<UInt64> _fld2;
- private BooleanBinaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestCUInt64()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<UInt64, UInt64>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestC), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt64>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt64>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((UInt64*)(pClsVar1)),
+ Sse2.LoadVector128((UInt64*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestC(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestC(left, right);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestC(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestCUInt64();
+
+ fixed (Vector128<UInt64>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt64>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ fixed (Vector128<UInt64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestC(
+ Sse2.LoadVector128((UInt64*)(&test._fld1)),
+ Sse2.LoadVector128((UInt64*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, Vector128<UInt64> op2, bool result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt64[] left, UInt64[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((~left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestC)}<UInt64>(Vector128<UInt64>, Vector128<UInt64>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Byte.cs
index c2509ec475..f5a86d3c60 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Byte.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestMixOnesZerosByte()
{
- var test = new BooleanTwoComparisonOpTest__TestMixOnesZerosByte();
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosByte();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestMixOnesZerosByte
+ public sealed unsafe class BooleanBinaryOpTest__TestMixOnesZerosByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestMixOnesZerosByte testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestMixOnesZerosByte testClass)
{
var result = Sse41.TestMixOnesZeros(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestMixOnesZerosByte testClass)
+ {
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ fixed (Vector128<Byte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<Byte, Byte> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestMixOnesZerosByte()
+ static BooleanBinaryOpTest__TestMixOnesZerosByte()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
}
- public BooleanTwoComparisonOpTest__TestMixOnesZerosByte()
+ public BooleanBinaryOpTest__TestMixOnesZerosByte()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<Byte, Byte>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Byte>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Byte>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Byte*)(pClsVar1)),
+ Sse2.LoadVector128((Byte*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestMixOnesZerosByte();
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosByte();
var result = Sse41.TestMixOnesZeros(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosByte();
+
+ fixed (Vector128<Byte>* pFld1 = &test._fld1)
+ fixed (Vector128<Byte>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ fixed (Vector128<Byte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Byte*)(&test._fld1)),
+ Sse2.LoadVector128((Byte*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, bool result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Byte[] left, Byte[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestMixOnesZeros)}<Byte>(Vector128<Byte>, Vector128<Byte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Int16.cs
index 3f2a6eceb6..3a462a92fa 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Int16.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestMixOnesZerosInt16()
{
- var test = new BooleanTwoComparisonOpTest__TestMixOnesZerosInt16();
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosInt16();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestMixOnesZerosInt16
+ public sealed unsafe class BooleanBinaryOpTest__TestMixOnesZerosInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestMixOnesZerosInt16 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestMixOnesZerosInt16 testClass)
{
var result = Sse41.TestMixOnesZeros(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestMixOnesZerosInt16 testClass)
+ {
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<Int16, Int16> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestMixOnesZerosInt16()
+ static BooleanBinaryOpTest__TestMixOnesZerosInt16()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
}
- public BooleanTwoComparisonOpTest__TestMixOnesZerosInt16()
+ public BooleanBinaryOpTest__TestMixOnesZerosInt16()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<Int16, Int16>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int16>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Int16*)(pClsVar1)),
+ Sse2.LoadVector128((Int16*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestMixOnesZerosInt16();
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosInt16();
var result = Sse41.TestMixOnesZeros(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosInt16();
+
+ fixed (Vector128<Int16>* pFld1 = &test._fld1)
+ fixed (Vector128<Int16>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Int16*)(&test._fld1)),
+ Sse2.LoadVector128((Int16*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, bool result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int16[] left, Int16[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestMixOnesZeros)}<Int16>(Vector128<Int16>, Vector128<Int16>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Int32.cs
index 0e5f130ce8..e6109177ab 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Int32.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestMixOnesZerosInt32()
{
- var test = new BooleanTwoComparisonOpTest__TestMixOnesZerosInt32();
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosInt32();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestMixOnesZerosInt32
+ public sealed unsafe class BooleanBinaryOpTest__TestMixOnesZerosInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestMixOnesZerosInt32 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestMixOnesZerosInt32 testClass)
{
var result = Sse41.TestMixOnesZeros(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestMixOnesZerosInt32 testClass)
+ {
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<Int32, Int32> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestMixOnesZerosInt32()
+ static BooleanBinaryOpTest__TestMixOnesZerosInt32()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
}
- public BooleanTwoComparisonOpTest__TestMixOnesZerosInt32()
+ public BooleanBinaryOpTest__TestMixOnesZerosInt32()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<Int32, Int32>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int32>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Int32*)(pClsVar1)),
+ Sse2.LoadVector128((Int32*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestMixOnesZerosInt32();
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosInt32();
var result = Sse41.TestMixOnesZeros(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosInt32();
+
+ fixed (Vector128<Int32>* pFld1 = &test._fld1)
+ fixed (Vector128<Int32>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Int32*)(&test._fld1)),
+ Sse2.LoadVector128((Int32*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, bool result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int32[] left, Int32[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestMixOnesZeros)}<Int32>(Vector128<Int32>, Vector128<Int32>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Int64.cs
index 9f2b53ba61..d1d1ad7c29 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.Int64.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestMixOnesZerosInt64()
{
- var test = new BooleanTwoComparisonOpTest__TestMixOnesZerosInt64();
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosInt64();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestMixOnesZerosInt64
+ public sealed unsafe class BooleanBinaryOpTest__TestMixOnesZerosInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int64> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestMixOnesZerosInt64 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestMixOnesZerosInt64 testClass)
{
var result = Sse41.TestMixOnesZeros(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestMixOnesZerosInt64 testClass)
+ {
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ fixed (Vector128<Int64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int64> _fld1;
private Vector128<Int64> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<Int64, Int64> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestMixOnesZerosInt64()
+ static BooleanBinaryOpTest__TestMixOnesZerosInt64()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
}
- public BooleanTwoComparisonOpTest__TestMixOnesZerosInt64()
+ public BooleanBinaryOpTest__TestMixOnesZerosInt64()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<Int64, Int64>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int64>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int64>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Int64*)(pClsVar1)),
+ Sse2.LoadVector128((Int64*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestMixOnesZerosInt64();
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosInt64();
var result = Sse41.TestMixOnesZeros(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosInt64();
+
+ fixed (Vector128<Int64>* pFld1 = &test._fld1)
+ fixed (Vector128<Int64>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ fixed (Vector128<Int64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((Int64*)(&test._fld1)),
+ Sse2.LoadVector128((Int64*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, Vector128<Int64> op2, bool result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int64[] left, Int64[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestMixOnesZeros)}<Int64>(Vector128<Int64>, Vector128<Int64>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.SByte.cs
index df6ad0e17a..7502291f20 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.SByte.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestMixOnesZerosSByte()
{
- var test = new BooleanTwoComparisonOpTest__TestMixOnesZerosSByte();
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosSByte();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestMixOnesZerosSByte
+ public sealed unsafe class BooleanBinaryOpTest__TestMixOnesZerosSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestMixOnesZerosSByte testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestMixOnesZerosSByte testClass)
{
var result = Sse41.TestMixOnesZeros(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestMixOnesZerosSByte testClass)
+ {
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ fixed (Vector128<SByte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<SByte, SByte> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestMixOnesZerosSByte()
+ static BooleanBinaryOpTest__TestMixOnesZerosSByte()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
}
- public BooleanTwoComparisonOpTest__TestMixOnesZerosSByte()
+ public BooleanBinaryOpTest__TestMixOnesZerosSByte()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<SByte, SByte>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<SByte>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<SByte>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((SByte*)(pClsVar1)),
+ Sse2.LoadVector128((SByte*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestMixOnesZerosSByte();
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosSByte();
var result = Sse41.TestMixOnesZeros(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosSByte();
+
+ fixed (Vector128<SByte>* pFld1 = &test._fld1)
+ fixed (Vector128<SByte>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ fixed (Vector128<SByte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((SByte*)(&test._fld1)),
+ Sse2.LoadVector128((SByte*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, bool result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(SByte[] left, SByte[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestMixOnesZeros)}<SByte>(Vector128<SByte>, Vector128<SByte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.UInt16.cs
index 35e2e1982b..74208d5e35 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.UInt16.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestMixOnesZerosUInt16()
{
- var test = new BooleanTwoComparisonOpTest__TestMixOnesZerosUInt16();
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosUInt16();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestMixOnesZerosUInt16
+ public sealed unsafe class BooleanBinaryOpTest__TestMixOnesZerosUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestMixOnesZerosUInt16 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestMixOnesZerosUInt16 testClass)
{
var result = Sse41.TestMixOnesZeros(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestMixOnesZerosUInt16 testClass)
+ {
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ fixed (Vector128<UInt16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestMixOnesZerosUInt16()
+ static BooleanBinaryOpTest__TestMixOnesZerosUInt16()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
}
- public BooleanTwoComparisonOpTest__TestMixOnesZerosUInt16()
+ public BooleanBinaryOpTest__TestMixOnesZerosUInt16()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<UInt16, UInt16>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt16>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((UInt16*)(pClsVar1)),
+ Sse2.LoadVector128((UInt16*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestMixOnesZerosUInt16();
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosUInt16();
var result = Sse41.TestMixOnesZeros(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosUInt16();
+
+ fixed (Vector128<UInt16>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt16>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ fixed (Vector128<UInt16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((UInt16*)(&test._fld1)),
+ Sse2.LoadVector128((UInt16*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, bool result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt16[] left, UInt16[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestMixOnesZeros)}<UInt16>(Vector128<UInt16>, Vector128<UInt16>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.UInt32.cs
index 9256682cbc..64950fc5c7 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.UInt32.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestMixOnesZerosUInt32()
{
- var test = new BooleanTwoComparisonOpTest__TestMixOnesZerosUInt32();
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosUInt32();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestMixOnesZerosUInt32
+ public sealed unsafe class BooleanBinaryOpTest__TestMixOnesZerosUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestMixOnesZerosUInt32 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestMixOnesZerosUInt32 testClass)
{
var result = Sse41.TestMixOnesZeros(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestMixOnesZerosUInt32 testClass)
+ {
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ fixed (Vector128<UInt32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestMixOnesZerosUInt32()
+ static BooleanBinaryOpTest__TestMixOnesZerosUInt32()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
}
- public BooleanTwoComparisonOpTest__TestMixOnesZerosUInt32()
+ public BooleanBinaryOpTest__TestMixOnesZerosUInt32()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<UInt32, UInt32>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt32>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((UInt32*)(pClsVar1)),
+ Sse2.LoadVector128((UInt32*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestMixOnesZerosUInt32();
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosUInt32();
var result = Sse41.TestMixOnesZeros(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosUInt32();
+
+ fixed (Vector128<UInt32>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt32>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ fixed (Vector128<UInt32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((UInt32*)(&test._fld1)),
+ Sse2.LoadVector128((UInt32*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, bool result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt32[] left, UInt32[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestMixOnesZeros)}<UInt32>(Vector128<UInt32>, Vector128<UInt32>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.UInt64.cs
index 138c791e1f..b97e93a2f3 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestMixOnesZeros.UInt64.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestMixOnesZerosUInt64()
{
- var test = new BooleanTwoComparisonOpTest__TestMixOnesZerosUInt64();
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosUInt64();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestMixOnesZerosUInt64
+ public sealed unsafe class BooleanBinaryOpTest__TestMixOnesZerosUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt64> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestMixOnesZerosUInt64 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestMixOnesZerosUInt64 testClass)
{
var result = Sse41.TestMixOnesZeros(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestMixOnesZerosUInt64 testClass)
+ {
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ fixed (Vector128<UInt64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt64> _fld1;
private Vector128<UInt64> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestMixOnesZerosUInt64()
+ static BooleanBinaryOpTest__TestMixOnesZerosUInt64()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
}
- public BooleanTwoComparisonOpTest__TestMixOnesZerosUInt64()
+ public BooleanBinaryOpTest__TestMixOnesZerosUInt64()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<UInt64, UInt64>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestMixOnesZeros), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt64>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt64>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((UInt64*)(pClsVar1)),
+ Sse2.LoadVector128((UInt64*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestMixOnesZeros(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestMixOnesZeros(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestMixOnesZerosUInt64();
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosUInt64();
var result = Sse41.TestMixOnesZeros(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestMixOnesZerosUInt64();
+
+ fixed (Vector128<UInt64>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt64>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ fixed (Vector128<UInt64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestMixOnesZeros(
+ Sse2.LoadVector128((UInt64*)(&test._fld1)),
+ Sse2.LoadVector128((UInt64*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, Vector128<UInt64> op2, bool result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt64[] left, UInt64[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestMixOnesZeros)}<UInt64>(Vector128<UInt64>, Vector128<UInt64>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Byte.cs
index a146257773..f842ef98e9 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Byte.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestNotZAndNotCByte()
{
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCByte();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCByte();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestNotZAndNotCByte
+ public sealed unsafe class BooleanBinaryOpTest__TestNotZAndNotCByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestNotZAndNotCByte testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestNotZAndNotCByte testClass)
{
var result = Sse41.TestNotZAndNotC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestNotZAndNotCByte testClass)
+ {
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ fixed (Vector128<Byte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<Byte, Byte> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestNotZAndNotCByte()
+ static BooleanBinaryOpTest__TestNotZAndNotCByte()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar1), ref Unsafe.As<Byte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Byte>, byte>(ref _clsVar2), ref Unsafe.As<Byte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Byte>>());
}
- public BooleanTwoComparisonOpTest__TestNotZAndNotCByte()
+ public BooleanBinaryOpTest__TestNotZAndNotCByte()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<Byte, Byte>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Byte>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Byte>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Byte*)(pClsVar1)),
+ Sse2.LoadVector128((Byte*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCByte();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCByte();
var result = Sse41.TestNotZAndNotC(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCByte();
+
+ fixed (Vector128<Byte>* pFld1 = &test._fld1)
+ fixed (Vector128<Byte>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ fixed (Vector128<Byte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Byte*)(&test._fld1)),
+ Sse2.LoadVector128((Byte*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, bool result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Byte[] left, Byte[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestNotZAndNotC)}<Byte>(Vector128<Byte>, Vector128<Byte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Int16.cs
index 43c6f925de..9ff933346b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Int16.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestNotZAndNotCInt16()
{
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCInt16();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt16();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestNotZAndNotCInt16
+ public sealed unsafe class BooleanBinaryOpTest__TestNotZAndNotCInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestNotZAndNotCInt16 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestNotZAndNotCInt16 testClass)
{
var result = Sse41.TestNotZAndNotC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestNotZAndNotCInt16 testClass)
+ {
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<Int16, Int16> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestNotZAndNotCInt16()
+ static BooleanBinaryOpTest__TestNotZAndNotCInt16()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar2), ref Unsafe.As<Int16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
}
- public BooleanTwoComparisonOpTest__TestNotZAndNotCInt16()
+ public BooleanBinaryOpTest__TestNotZAndNotCInt16()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<Int16, Int16>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int16>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Int16*)(pClsVar1)),
+ Sse2.LoadVector128((Int16*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCInt16();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt16();
var result = Sse41.TestNotZAndNotC(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt16();
+
+ fixed (Vector128<Int16>* pFld1 = &test._fld1)
+ fixed (Vector128<Int16>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Int16*)(&test._fld1)),
+ Sse2.LoadVector128((Int16*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, bool result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int16[] left, Int16[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestNotZAndNotC)}<Int16>(Vector128<Int16>, Vector128<Int16>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Int32.cs
index 25f622ed29..3398f01bc5 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Int32.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestNotZAndNotCInt32()
{
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCInt32();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt32();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestNotZAndNotCInt32
+ public sealed unsafe class BooleanBinaryOpTest__TestNotZAndNotCInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestNotZAndNotCInt32 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestNotZAndNotCInt32 testClass)
{
var result = Sse41.TestNotZAndNotC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestNotZAndNotCInt32 testClass)
+ {
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<Int32, Int32> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestNotZAndNotCInt32()
+ static BooleanBinaryOpTest__TestNotZAndNotCInt32()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar2), ref Unsafe.As<Int32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
}
- public BooleanTwoComparisonOpTest__TestNotZAndNotCInt32()
+ public BooleanBinaryOpTest__TestNotZAndNotCInt32()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<Int32, Int32>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int32>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Int32*)(pClsVar1)),
+ Sse2.LoadVector128((Int32*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCInt32();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt32();
var result = Sse41.TestNotZAndNotC(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt32();
+
+ fixed (Vector128<Int32>* pFld1 = &test._fld1)
+ fixed (Vector128<Int32>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Int32*)(&test._fld1)),
+ Sse2.LoadVector128((Int32*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, bool result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int32[] left, Int32[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestNotZAndNotC)}<Int32>(Vector128<Int32>, Vector128<Int32>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Int64.cs
index ca6cd0a186..20d2324293 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.Int64.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestNotZAndNotCInt64()
{
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCInt64();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt64();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestNotZAndNotCInt64
+ public sealed unsafe class BooleanBinaryOpTest__TestNotZAndNotCInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int64> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestNotZAndNotCInt64 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestNotZAndNotCInt64 testClass)
{
var result = Sse41.TestNotZAndNotC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestNotZAndNotCInt64 testClass)
+ {
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ fixed (Vector128<Int64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int64> _fld1;
private Vector128<Int64> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<Int64, Int64> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestNotZAndNotCInt64()
+ static BooleanBinaryOpTest__TestNotZAndNotCInt64()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar1), ref Unsafe.As<Int64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int64>, byte>(ref _clsVar2), ref Unsafe.As<Int64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<Int64>>());
}
- public BooleanTwoComparisonOpTest__TestNotZAndNotCInt64()
+ public BooleanBinaryOpTest__TestNotZAndNotCInt64()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<Int64, Int64>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int64>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int64>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Int64*)(pClsVar1)),
+ Sse2.LoadVector128((Int64*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCInt64();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt64();
var result = Sse41.TestNotZAndNotC(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCInt64();
+
+ fixed (Vector128<Int64>* pFld1 = &test._fld1)
+ fixed (Vector128<Int64>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ fixed (Vector128<Int64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((Int64*)(&test._fld1)),
+ Sse2.LoadVector128((Int64*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, Vector128<Int64> op2, bool result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int64[] left, Int64[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestNotZAndNotC)}<Int64>(Vector128<Int64>, Vector128<Int64>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.SByte.cs
index 2703114989..b2c6050052 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.SByte.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestNotZAndNotCSByte()
{
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCSByte();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCSByte();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestNotZAndNotCSByte
+ public sealed unsafe class BooleanBinaryOpTest__TestNotZAndNotCSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestNotZAndNotCSByte testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestNotZAndNotCSByte testClass)
{
var result = Sse41.TestNotZAndNotC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestNotZAndNotCSByte testClass)
+ {
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ fixed (Vector128<SByte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<SByte, SByte> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestNotZAndNotCSByte()
+ static BooleanBinaryOpTest__TestNotZAndNotCSByte()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar2), ref Unsafe.As<SByte, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
}
- public BooleanTwoComparisonOpTest__TestNotZAndNotCSByte()
+ public BooleanBinaryOpTest__TestNotZAndNotCSByte()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<SByte, SByte>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<SByte>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<SByte>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((SByte*)(pClsVar1)),
+ Sse2.LoadVector128((SByte*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCSByte();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCSByte();
var result = Sse41.TestNotZAndNotC(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCSByte();
+
+ fixed (Vector128<SByte>* pFld1 = &test._fld1)
+ fixed (Vector128<SByte>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ fixed (Vector128<SByte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((SByte*)(&test._fld1)),
+ Sse2.LoadVector128((SByte*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, bool result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(SByte[] left, SByte[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestNotZAndNotC)}<SByte>(Vector128<SByte>, Vector128<SByte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.UInt16.cs
index 9687b275c0..a7dcd0a0e8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.UInt16.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestNotZAndNotCUInt16()
{
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCUInt16();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt16();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestNotZAndNotCUInt16
+ public sealed unsafe class BooleanBinaryOpTest__TestNotZAndNotCUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestNotZAndNotCUInt16 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestNotZAndNotCUInt16 testClass)
{
var result = Sse41.TestNotZAndNotC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestNotZAndNotCUInt16 testClass)
+ {
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ fixed (Vector128<UInt16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestNotZAndNotCUInt16()
+ static BooleanBinaryOpTest__TestNotZAndNotCUInt16()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar1), ref Unsafe.As<UInt16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt16>, byte>(ref _clsVar2), ref Unsafe.As<UInt16, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
}
- public BooleanTwoComparisonOpTest__TestNotZAndNotCUInt16()
+ public BooleanBinaryOpTest__TestNotZAndNotCUInt16()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<UInt16, UInt16>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt16>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((UInt16*)(pClsVar1)),
+ Sse2.LoadVector128((UInt16*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCUInt16();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt16();
var result = Sse41.TestNotZAndNotC(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt16();
+
+ fixed (Vector128<UInt16>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt16>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ fixed (Vector128<UInt16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((UInt16*)(&test._fld1)),
+ Sse2.LoadVector128((UInt16*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, bool result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt16[] left, UInt16[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestNotZAndNotC)}<UInt16>(Vector128<UInt16>, Vector128<UInt16>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.UInt32.cs
index 41c2c6630a..6cef890511 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.UInt32.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestNotZAndNotCUInt32()
{
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCUInt32();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt32();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestNotZAndNotCUInt32
+ public sealed unsafe class BooleanBinaryOpTest__TestNotZAndNotCUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestNotZAndNotCUInt32 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestNotZAndNotCUInt32 testClass)
{
var result = Sse41.TestNotZAndNotC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestNotZAndNotCUInt32 testClass)
+ {
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ fixed (Vector128<UInt32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestNotZAndNotCUInt32()
+ static BooleanBinaryOpTest__TestNotZAndNotCUInt32()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar1), ref Unsafe.As<UInt32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt32>, byte>(ref _clsVar2), ref Unsafe.As<UInt32, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
}
- public BooleanTwoComparisonOpTest__TestNotZAndNotCUInt32()
+ public BooleanBinaryOpTest__TestNotZAndNotCUInt32()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<UInt32, UInt32>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt32>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((UInt32*)(pClsVar1)),
+ Sse2.LoadVector128((UInt32*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCUInt32();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt32();
var result = Sse41.TestNotZAndNotC(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt32();
+
+ fixed (Vector128<UInt32>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt32>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ fixed (Vector128<UInt32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((UInt32*)(&test._fld1)),
+ Sse2.LoadVector128((UInt32*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, bool result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt32[] left, UInt32[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestNotZAndNotC)}<UInt32>(Vector128<UInt32>, Vector128<UInt32>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.UInt64.cs
index 6a4ef41e59..069a10adac 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestNotZAndNotC.UInt64.cs
@@ -21,7 +21,7 @@ namespace JIT.HardwareIntrinsics.X86
{
private static void TestNotZAndNotCUInt64()
{
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCUInt64();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt64();
if (test.IsSupported)
{
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -89,8 +119,54 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- public sealed unsafe class BooleanTwoComparisonOpTest__TestNotZAndNotCUInt64
+ public sealed unsafe class BooleanBinaryOpTest__TestNotZAndNotCUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt64> _fld1;
@@ -108,11 +184,25 @@ namespace JIT.HardwareIntrinsics.X86
return testStruct;
}
- public void RunStructFldScenario(BooleanTwoComparisonOpTest__TestNotZAndNotCUInt64 testClass)
+ public void RunStructFldScenario(BooleanBinaryOpTest__TestNotZAndNotCUInt64 testClass)
{
var result = Sse41.TestNotZAndNotC(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestNotZAndNotCUInt64 testClass)
+ {
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ fixed (Vector128<UInt64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,9 +219,9 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt64> _fld1;
private Vector128<UInt64> _fld2;
- private BooleanTwoComparisonOpTest__DataTable<UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
- static BooleanTwoComparisonOpTest__TestNotZAndNotCUInt64()
+ static BooleanBinaryOpTest__TestNotZAndNotCUInt64()
{
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar1), ref Unsafe.As<UInt64, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
@@ -139,7 +229,7 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<UInt64>, byte>(ref _clsVar2), ref Unsafe.As<UInt64, byte>(ref _data2[0]), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
}
- public BooleanTwoComparisonOpTest__TestNotZAndNotCUInt64()
+ public BooleanBinaryOpTest__TestNotZAndNotCUInt64()
{
Succeeded = true;
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new BooleanTwoComparisonOpTest__DataTable<UInt64, UInt64>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestNotZAndNotC), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,49 +334,83 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt64>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt64>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((UInt64*)(pClsVar1)),
+ Sse2.LoadVector128((UInt64*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestNotZAndNotC(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestNotZAndNotC(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
- var test = new BooleanTwoComparisonOpTest__TestNotZAndNotCUInt64();
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt64();
var result = Sse41.TestNotZAndNotC(test._fld1, test._fld2);
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestNotZAndNotCUInt64();
+
+ fixed (Vector128<UInt64>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt64>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ fixed (Vector128<UInt64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestNotZAndNotC(
+ Sse2.LoadVector128((UInt64*)(&test._fld1)),
+ Sse2.LoadVector128((UInt64*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, Vector128<UInt64> op2, bool result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt64[] left, UInt64[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult1 = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -384,12 +535,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult2 &= (((~left[i] & right[i]) == 0));
}
- if (((expectedResult1 == false) && (expectedResult2 == false)) != result)
+ succeeded = (((expectedResult1 == false) && (expectedResult2 == false)) == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestNotZAndNotC)}<UInt64>(Vector128<UInt64>, Vector128<UInt64>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Byte.cs
index cfd39b31e9..7e5e3de61f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Byte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestZByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestZ(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestZByte testClass)
+ {
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ fixed (Vector128<Byte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private BooleanBinaryOpTest__DataTable<Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestZByte()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Byte, Byte>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Byte>), typeof(Vector128<Byte>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Byte>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Byte>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Byte*)(pClsVar1)),
+ Sse2.LoadVector128((Byte*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestZ(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestZ(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestZ(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestZByte();
+
+ fixed (Vector128<Byte>* pFld1 = &test._fld1)
+ fixed (Vector128<Byte>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Byte>* pFld1 = &_fld1)
+ fixed (Vector128<Byte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Byte*)(pFld1)),
+ Sse2.LoadVector128((Byte*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Byte*)(&test._fld1)),
+ Sse2.LoadVector128((Byte*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, bool result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Byte[] left, Byte[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestZ)}<Byte>(Vector128<Byte>, Vector128<Byte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Int16.cs
index 04bc01e213..ffc8b7d380 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Int16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestZInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestZ(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestZInt16 testClass)
+ {
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private BooleanBinaryOpTest__DataTable<Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestZInt16()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Int16, Int16>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int16>), typeof(Vector128<Int16>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int16>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Int16*)(pClsVar1)),
+ Sse2.LoadVector128((Int16*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestZ(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestZ(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestZ(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestZInt16();
+
+ fixed (Vector128<Int16>* pFld1 = &test._fld1)
+ fixed (Vector128<Int16>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Int16*)(&test._fld1)),
+ Sse2.LoadVector128((Int16*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, bool result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int16[] left, Int16[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestZ)}<Int16>(Vector128<Int16>, Vector128<Int16>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Int32.cs
index d4201ca891..f27ede8144 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Int32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestZInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestZ(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestZInt32 testClass)
+ {
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private BooleanBinaryOpTest__DataTable<Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestZInt32()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Int32, Int32>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int32>), typeof(Vector128<Int32>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int32>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Int32*)(pClsVar1)),
+ Sse2.LoadVector128((Int32*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestZ(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestZ(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestZ(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestZInt32();
+
+ fixed (Vector128<Int32>* pFld1 = &test._fld1)
+ fixed (Vector128<Int32>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Int32*)(&test._fld1)),
+ Sse2.LoadVector128((Int32*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, bool result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int32[] left, Int32[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestZ)}<Int32>(Vector128<Int32>, Vector128<Int32>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Int64.cs
index 9391975dfc..17eaf021be 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.Int64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestZInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int64> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestZ(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestZInt64 testClass)
+ {
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ fixed (Vector128<Int64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int64> _fld1;
private Vector128<Int64> _fld2;
- private BooleanBinaryOpTest__DataTable<Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestZInt64()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<Int64, Int64>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<Int64>), typeof(Vector128<Int64>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int64>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int64>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Int64*)(pClsVar1)),
+ Sse2.LoadVector128((Int64*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestZ(left, right);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestZ(left, right);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestZ(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestZInt64();
+
+ fixed (Vector128<Int64>* pFld1 = &test._fld1)
+ fixed (Vector128<Int64>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int64>* pFld1 = &_fld1)
+ fixed (Vector128<Int64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Int64*)(pFld1)),
+ Sse2.LoadVector128((Int64*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((Int64*)(&test._fld1)),
+ Sse2.LoadVector128((Int64*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, Vector128<Int64> op2, bool result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(Int64[] left, Int64[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestZ)}<Int64>(Vector128<Int64>, Vector128<Int64>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.SByte.cs
index 2dc9dc7b93..69a0793ad0 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.SByte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestZSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestZ(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestZSByte testClass)
+ {
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ fixed (Vector128<SByte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private BooleanBinaryOpTest__DataTable<SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestZSByte()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<SByte, SByte>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<SByte>), typeof(Vector128<SByte>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<SByte>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<SByte>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((SByte*)(pClsVar1)),
+ Sse2.LoadVector128((SByte*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestZ(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestZ(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestZ(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestZSByte();
+
+ fixed (Vector128<SByte>* pFld1 = &test._fld1)
+ fixed (Vector128<SByte>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ fixed (Vector128<SByte>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((SByte*)(pFld1)),
+ Sse2.LoadVector128((SByte*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((SByte*)(&test._fld1)),
+ Sse2.LoadVector128((SByte*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, bool result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(SByte[] left, SByte[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestZ)}<SByte>(Vector128<SByte>, Vector128<SByte>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.UInt16.cs
index 83e1090e6a..2ab4d704f7 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.UInt16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestZUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt16[] inArray1, UInt16[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt16> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestZ(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestZUInt16 testClass)
+ {
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ fixed (Vector128<UInt16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt16> _fld1;
private Vector128<UInt16> _fld2;
- private BooleanBinaryOpTest__DataTable<UInt16, UInt16> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestZUInt16()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt16(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<UInt16, UInt16>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt16>), typeof(Vector128<UInt16>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt16>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((UInt16*)(pClsVar1)),
+ Sse2.LoadVector128((UInt16*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestZ(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt16>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestZ(left, right);
+ var op1 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestZ(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt16*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestZUInt16();
+
+ fixed (Vector128<UInt16>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt16>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt16>* pFld1 = &_fld1)
+ fixed (Vector128<UInt16>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((UInt16*)(pFld1)),
+ Sse2.LoadVector128((UInt16*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((UInt16*)(&test._fld1)),
+ Sse2.LoadVector128((UInt16*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt16> left, Vector128<UInt16> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt16> op1, Vector128<UInt16> op2, bool result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt16[] inArray1 = new UInt16[Op1ElementCount];
UInt16[] inArray2 = new UInt16[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt16[] left, UInt16[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestZ)}<UInt16>(Vector128<UInt16>, Vector128<UInt16>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.UInt32.cs
index 81ff617828..8d0be221b4 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.UInt32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestZUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt32[] inArray1, UInt32[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt32> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestZ(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestZUInt32 testClass)
+ {
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ fixed (Vector128<UInt32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt32> _fld1;
private Vector128<UInt32> _fld2;
- private BooleanBinaryOpTest__DataTable<UInt32, UInt32> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestZUInt32()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt32(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<UInt32, UInt32>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt32>), typeof(Vector128<UInt32>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt32>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((UInt32*)(pClsVar1)),
+ Sse2.LoadVector128((UInt32*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestZ(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt32>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestZ(left, right);
+ var op1 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestZ(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt32*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestZUInt32();
+
+ fixed (Vector128<UInt32>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt32>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt32>* pFld1 = &_fld1)
+ fixed (Vector128<UInt32>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((UInt32*)(pFld1)),
+ Sse2.LoadVector128((UInt32*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((UInt32*)(&test._fld1)),
+ Sse2.LoadVector128((UInt32*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt32> left, Vector128<UInt32> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt32> op1, Vector128<UInt32> op2, bool result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt32[] inArray1 = new UInt32[Op1ElementCount];
UInt32[] inArray2 = new UInt32[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt32[] left, UInt32[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestZ)}<UInt32>(Vector128<UInt32>, Vector128<UInt32>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.UInt64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.UInt64.cs
index fc51152b8f..30a4a7a2bd 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.UInt64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse41/TestZ.UInt64.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,52 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class BooleanBinaryOpTest__TestZUInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+
+ private ulong alignment;
+
+ public DataTable(UInt64[] inArray1, UInt64[] inArray2, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<UInt64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<UInt64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<UInt64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<UInt64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<UInt64> _fld1;
@@ -113,6 +189,20 @@ namespace JIT.HardwareIntrinsics.X86
var result = Sse41.TestZ(_fld1, _fld2);
testClass.ValidateResult(_fld1, _fld2, result);
}
+
+ public void RunStructFldScenario_Load(BooleanBinaryOpTest__TestZUInt64 testClass)
+ {
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ fixed (Vector128<UInt64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2))
+ );
+
+ testClass.ValidateResult(_fld1, _fld2, result);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -129,7 +219,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<UInt64> _fld1;
private Vector128<UInt64> _fld2;
- private BooleanBinaryOpTest__DataTable<UInt64, UInt64> _dataTable;
+ private DataTable _dataTable;
static BooleanBinaryOpTest__TestZUInt64()
{
@@ -150,7 +240,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetUInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetUInt64(); }
- _dataTable = new BooleanBinaryOpTest__DataTable<UInt64, UInt64>(_data1, _data2, LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, LargestVectorSize);
}
public bool IsSupported => Sse41.IsSupported;
@@ -197,51 +287,39 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_UnsafeRead));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr),
Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr)
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_Load));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr)),
Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunReflectionScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunReflectionScenario_LoadAligned));
- var method = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) });
-
- if (method != null)
- {
- var result = method.Invoke(null, new object[] {
+ var result = typeof(Sse41).GetMethod(nameof(Sse41.TestZ), new Type[] { typeof(Vector128<UInt64>), typeof(Vector128<UInt64>) })
+ .Invoke(null, new object[] {
Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr)),
Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr))
});
- ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
- }
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.inArray2Ptr, (bool)(result));
}
public void RunClsVarScenario()
@@ -256,37 +334,53 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, result);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<UInt64>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<UInt64>* pClsVar2 = &_clsVar2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((UInt64*)(pClsVar1)),
+ Sse2.LoadVector128((UInt64*)(pClsVar2))
+ );
+
+ ValidateResult(_clsVar1, _clsVar2, result);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
- var result = Sse41.TestZ(left, right);
+ var op1 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<UInt64>>(_dataTable.inArray2Ptr);
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestZ(left, right);
+ var op1 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
- var result = Sse41.TestZ(left, right);
+ var op1 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((UInt64*)(_dataTable.inArray2Ptr));
+ var result = Sse41.TestZ(op1, op2);
- ValidateResult(left, right, result);
+ ValidateResult(op1, op2, result);
}
public void RunClassLclFldScenario()
@@ -299,6 +393,24 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new BooleanBinaryOpTest__TestZUInt64();
+
+ fixed (Vector128<UInt64>* pFld1 = &test._fld1)
+ fixed (Vector128<UInt64>* pFld2 = &test._fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -308,6 +420,22 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, result);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<UInt64>* pFld1 = &_fld1)
+ fixed (Vector128<UInt64>* pFld2 = &_fld2)
+ {
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((UInt64*)(pFld1)),
+ Sse2.LoadVector128((UInt64*)(pFld2))
+ );
+
+ ValidateResult(_fld1, _fld2, result);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -317,6 +445,19 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, result);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Sse41.TestZ(
+ Sse2.LoadVector128((UInt64*)(&test._fld1)),
+ Sse2.LoadVector128((UInt64*)(&test._fld2))
+ );
+
+ ValidateResult(test._fld1, test._fld2, result);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -325,6 +466,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -346,30 +495,32 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<UInt64> left, Vector128<UInt64> right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<UInt64> op1, Vector128<UInt64> op2, bool result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), op2);
ValidateResult(inArray1, inArray2, result, method);
}
- private void ValidateResult(void* left, void* right, bool result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, bool result, [CallerMemberName] string method = "")
{
UInt64[] inArray1 = new UInt64[Op1ElementCount];
UInt64[] inArray2 = new UInt64[Op2ElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<UInt64>>());
ValidateResult(inArray1, inArray2, result, method);
}
private void ValidateResult(UInt64[] left, UInt64[] right, bool result, [CallerMemberName] string method = "")
{
+ bool succeeded = true;
+
var expectedResult = true;
for (var i = 0; i < Op1ElementCount; i++)
@@ -377,12 +528,14 @@ namespace JIT.HardwareIntrinsics.X86
expectedResult &= ((left[i] & right[i]) == 0);
}
- if (expectedResult != result)
+ succeeded = (expectedResult == result);
+
+ if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Sse41)}.{nameof(Sse41.TestZ)}<UInt64>(Vector128<UInt64>, Vector128<UInt64>): {method} failed:");
TestLibrary.TestFramework.LogInformation($" left: ({string.Join(", ", left)})");
TestLibrary.TestFramework.LogInformation($" right: ({string.Join(", ", right)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({result})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse42/CompareGreaterThan.Int64.cs b/tests/src/JIT/HardwareIntrinsics/X86/Sse42/CompareGreaterThan.Int64.cs
index b3e2d56d05..a6d1cf3b3c 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse42/CompareGreaterThan.Int64.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse42/CompareGreaterThan.Int64.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__CompareGreaterThanInt64
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int64[] inArray1, Int64[] inArray2, Int64[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int64>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int64>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int64, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int64, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int64> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int64> _fld1;
private Vector128<Int64> _fld2;
- private SimpleBinaryOpTest__DataTable<Int64, Int64, Int64> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__CompareGreaterThanInt64()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt64(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt64(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int64, Int64, Int64>(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int64[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Sse42.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
- var result = Sse42.CompareGreaterThan(left, right);
+ var op1 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int64>>(_dataTable.inArray2Ptr);
+ var result = Sse42.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse42.CompareGreaterThan(left, right);
+ var op1 = Sse2.LoadVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse42.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
- var result = Sse42.CompareGreaterThan(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int64*)(_dataTable.inArray2Ptr));
+ var result = Sse42.CompareGreaterThan(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int64> left, Vector128<Int64> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int64> op1, Vector128<Int64> op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int64[] inArray1 = new Int64[Op1ElementCount];
Int64[] inArray2 = new Int64[Op2ElementCount];
Int64[] outArray = new Int64[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int64>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int64>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int64>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int64, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int64>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse42/Sse42_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse42/Sse42_r.csproj
index b385d5c4ea..2196fdd8a5 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse42/Sse42_r.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse42/Sse42_r.csproj
@@ -30,8 +30,6 @@
<Compile Include="CompareGreaterThan.Int64.cs" />
<Compile Include="Program.Sse42.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Sse42/Sse42_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Sse42/Sse42_ro.csproj
index 8e9e960c3f..2105e9bff0 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Sse42/Sse42_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Sse42/Sse42_ro.csproj
@@ -30,8 +30,6 @@
<Compile Include="CompareGreaterThan.Int64.cs" />
<Compile Include="Program.Sse42.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleTernOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Abs.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Abs.Byte.cs
index a86174ab63..87985960db 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Abs.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Abs.Byte.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__AbsByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<SByte> _fld;
+ public Vector128<SByte> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref testStruct._fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__AbsByte testClass)
{
- var result = Ssse3.Abs(_fld);
+ var result = Ssse3.Abs(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__AbsByte testClass)
+ {
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ {
+ var result = Ssse3.Abs(
+ Sse2.LoadVector128((SByte*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<SByte>>() / sizeof(SByte);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<Byte>>() / sizeof(Byte);
- private static SByte[] _data = new SByte[Op1ElementCount];
+ private static SByte[] _data1 = new SByte[Op1ElementCount];
- private static Vector128<SByte> _clsVar;
+ private static Vector128<SByte> _clsVar1;
- private Vector128<SByte> _fld;
+ private Vector128<SByte> _fld1;
- private SimpleUnaryOpTest__DataTable<Byte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__AbsByte()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _clsVar1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
}
public SimpleUnaryOpTest__AbsByte()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld), ref Unsafe.As<SByte, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<SByte>, byte>(ref _fld1), ref Unsafe.As<SByte, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<Byte, SByte>(_data, new Byte[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
+ _dataTable = new DataTable(_data1, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Ssse3.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Ssse3.Abs(
- Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Ssse3.Abs(
- Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Ssse3.Abs(
- Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Ssse3).GetMethod(nameof(Ssse3.Abs), new Type[] { typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Ssse3).GetMethod(nameof(Ssse3.Abs), new Type[] { typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Ssse3).GetMethod(nameof(Ssse3.Abs), new Type[] { typeof(Vector128<SByte>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<Byte>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Ssse3.Abs(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<SByte>* pClsVar1 = &_clsVar1)
+ {
+ var result = Ssse3.Abs(
+ Sse2.LoadVector128((SByte*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<SByte>>(_dataTable.inArrayPtr);
- var result = Ssse3.Abs(firstOp);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var result = Ssse3.Abs(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((SByte*)(_dataTable.inArrayPtr));
- var result = Ssse3.Abs(firstOp);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var result = Ssse3.Abs(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArrayPtr));
- var result = Ssse3.Abs(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var result = Ssse3.Abs(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__AbsByte();
- var result = Ssse3.Abs(test._fld);
+ var result = Ssse3.Abs(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__AbsByte();
+
+ fixed (Vector128<SByte>* pFld1 = &test._fld1)
+ {
+ var result = Ssse3.Abs(
+ Sse2.LoadVector128((SByte*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Ssse3.Abs(_fld);
+ var result = Ssse3.Abs(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<SByte>* pFld1 = &_fld1)
+ {
+ var result = Ssse3.Abs(
+ Sse2.LoadVector128((SByte*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Ssse3.Abs(test._fld);
+ var result = Ssse3.Abs(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Ssse3.Abs(
+ Sse2.LoadVector128((SByte*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, void* result, [CallerMemberName] string method = "")
{
- SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] inArray1 = new SByte[Op1ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- SByte[] inArray = new SByte[Op1ElementCount];
+ SByte[] inArray1 = new SByte[Op1ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(SByte[] firstOp, Byte[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Ssse3)}.{nameof(Ssse3.Abs)}<Byte>(Vector128<SByte>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Abs.UInt16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Abs.UInt16.cs
index 39d7c7e8ae..a4a7bc7fc9 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Abs.UInt16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Abs.UInt16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__AbsUInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, UInt16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Int16> _fld;
+ public Vector128<Int16> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld), ref Unsafe.As<Int16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref testStruct._fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__AbsUInt16 testClass)
{
- var result = Ssse3.Abs(_fld);
+ var result = Ssse3.Abs(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__AbsUInt16 testClass)
+ {
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ {
+ var result = Ssse3.Abs(
+ Sse2.LoadVector128((Int16*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int16>>() / sizeof(Int16);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<UInt16>>() / sizeof(UInt16);
- private static Int16[] _data = new Int16[Op1ElementCount];
+ private static Int16[] _data1 = new Int16[Op1ElementCount];
- private static Vector128<Int16> _clsVar;
+ private static Vector128<Int16> _clsVar1;
- private Vector128<Int16> _fld;
+ private Vector128<Int16> _fld1;
- private SimpleUnaryOpTest__DataTable<UInt16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__AbsUInt16()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar), ref Unsafe.As<Int16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _clsVar1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
}
public SimpleUnaryOpTest__AbsUInt16()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld), ref Unsafe.As<Int16, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int16>, byte>(ref _fld1), ref Unsafe.As<Int16, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<UInt16, Int16>(_data, new UInt16[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
+ _dataTable = new DataTable(_data1, new UInt16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Ssse3.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Ssse3.Abs(
- Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Ssse3.Abs(
- Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Ssse3.Abs(
- Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Ssse3).GetMethod(nameof(Ssse3.Abs), new Type[] { typeof(Vector128<Int16>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Ssse3).GetMethod(nameof(Ssse3.Abs), new Type[] { typeof(Vector128<Int16>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Ssse3).GetMethod(nameof(Ssse3.Abs), new Type[] { typeof(Vector128<Int16>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt16>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Ssse3.Abs(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int16>* pClsVar1 = &_clsVar1)
+ {
+ var result = Ssse3.Abs(
+ Sse2.LoadVector128((Int16*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Int16>>(_dataTable.inArrayPtr);
- var result = Ssse3.Abs(firstOp);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var result = Ssse3.Abs(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Int16*)(_dataTable.inArrayPtr));
- var result = Ssse3.Abs(firstOp);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var result = Ssse3.Abs(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArrayPtr));
- var result = Ssse3.Abs(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var result = Ssse3.Abs(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__AbsUInt16();
- var result = Ssse3.Abs(test._fld);
+ var result = Ssse3.Abs(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__AbsUInt16();
+
+ fixed (Vector128<Int16>* pFld1 = &test._fld1)
+ {
+ var result = Ssse3.Abs(
+ Sse2.LoadVector128((Int16*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Ssse3.Abs(_fld);
+ var result = Ssse3.Abs(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ {
+ var result = Ssse3.Abs(
+ Sse2.LoadVector128((Int16*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Ssse3.Abs(test._fld);
+ var result = Ssse3.Abs(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Ssse3.Abs(
+ Sse2.LoadVector128((Int16*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, void* result, [CallerMemberName] string method = "")
{
- Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] inArray1 = new Int16[Op1ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Int16[] inArray = new Int16[Op1ElementCount];
+ Int16[] inArray1 = new Int16[Op1ElementCount];
UInt16[] outArray = new UInt16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt16>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Int16[] firstOp, UInt16[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Ssse3)}.{nameof(Ssse3.Abs)}<UInt16>(Vector128<Int16>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Abs.UInt32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Abs.UInt32.cs
index 5a6935c34f..c36b574e16 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Abs.UInt32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Abs.UInt32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,26 +121,84 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleUnaryOpTest__AbsUInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, UInt32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<UInt32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
- public Vector128<Int32> _fld;
+ public Vector128<Int32> _fld1;
public static TestStruct Create()
{
var testStruct = new TestStruct();
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref testStruct._fld), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref testStruct._fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
return testStruct;
}
public void RunStructFldScenario(SimpleUnaryOpTest__AbsUInt32 testClass)
{
- var result = Ssse3.Abs(_fld);
+ var result = Ssse3.Abs(_fld1);
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
- testClass.ValidateResult(_fld, testClass._dataTable.outArrayPtr);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
+
+ public void RunStructFldScenario_Load(SimpleUnaryOpTest__AbsUInt32 testClass)
+ {
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ {
+ var result = Ssse3.Abs(
+ Sse2.LoadVector128((Int32*)(pFld1))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, testClass._dataTable.outArrayPtr);
+ }
}
}
@@ -119,29 +207,29 @@ namespace JIT.HardwareIntrinsics.X86
private static readonly int Op1ElementCount = Unsafe.SizeOf<Vector128<Int32>>() / sizeof(Int32);
private static readonly int RetElementCount = Unsafe.SizeOf<Vector128<UInt32>>() / sizeof(UInt32);
- private static Int32[] _data = new Int32[Op1ElementCount];
+ private static Int32[] _data1 = new Int32[Op1ElementCount];
- private static Vector128<Int32> _clsVar;
+ private static Vector128<Int32> _clsVar1;
- private Vector128<Int32> _fld;
+ private Vector128<Int32> _fld1;
- private SimpleUnaryOpTest__DataTable<UInt32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleUnaryOpTest__AbsUInt32()
{
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _clsVar1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
}
public SimpleUnaryOpTest__AbsUInt32()
{
Succeeded = true;
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); }
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld), ref Unsafe.As<Int32, byte>(ref _data[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Vector128<Int32>, byte>(ref _fld1), ref Unsafe.As<Int32, byte>(ref _data1[0]), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- for (var i = 0; i < Op1ElementCount; i++) { _data[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleUnaryOpTest__DataTable<UInt32, Int32>(_data, new UInt32[RetElementCount], LargestVectorSize);
+ for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
+ _dataTable = new DataTable(_data1, new UInt32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Ssse3.IsSupported;
@@ -153,11 +241,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_UnsafeRead));
var result = Ssse3.Abs(
- Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr)
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_Load()
@@ -165,11 +253,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_Load));
var result = Ssse3.Abs(
- Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunBasicScenario_LoadAligned()
@@ -177,11 +265,11 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunBasicScenario_LoadAligned));
var result = Ssse3.Abs(
- Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr))
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_UnsafeRead()
@@ -190,11 +278,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Ssse3).GetMethod(nameof(Ssse3.Abs), new Type[] { typeof(Vector128<Int32>) })
.Invoke(null, new object[] {
- Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr)
+ Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr)
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_Load()
@@ -203,11 +291,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Ssse3).GetMethod(nameof(Ssse3.Abs), new Type[] { typeof(Vector128<Int32>) })
.Invoke(null, new object[] {
- Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr))
+ Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunReflectionScenario_LoadAligned()
@@ -216,11 +304,11 @@ namespace JIT.HardwareIntrinsics.X86
var result = typeof(Ssse3).GetMethod(nameof(Ssse3.Abs), new Type[] { typeof(Vector128<Int32>) })
.Invoke(null, new object[] {
- Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr))
+ Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr))
});
Unsafe.Write(_dataTable.outArrayPtr, (Vector128<UInt32>)(result));
- ValidateResult(_dataTable.inArrayPtr, _dataTable.outArrayPtr);
+ ValidateResult(_dataTable.inArray1Ptr, _dataTable.outArrayPtr);
}
public void RunClsVarScenario()
@@ -228,44 +316,59 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario));
var result = Ssse3.Abs(
- _clsVar
+ _clsVar1
);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_clsVar, _dataTable.outArrayPtr);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int32>* pClsVar1 = &_clsVar1)
+ {
+ var result = Ssse3.Abs(
+ Sse2.LoadVector128((Int32*)(pClsVar1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _dataTable.outArrayPtr);
+ }
}
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var firstOp = Unsafe.Read<Vector128<Int32>>(_dataTable.inArrayPtr);
- var result = Ssse3.Abs(firstOp);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var result = Ssse3.Abs(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var firstOp = Sse2.LoadVector128((Int32*)(_dataTable.inArrayPtr));
- var result = Ssse3.Abs(firstOp);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var result = Ssse3.Abs(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var firstOp = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArrayPtr));
- var result = Ssse3.Abs(firstOp);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var result = Ssse3.Abs(op1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(firstOp, _dataTable.outArrayPtr);
+ ValidateResult(op1, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -273,20 +376,52 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario));
var test = new SimpleUnaryOpTest__AbsUInt32();
- var result = Ssse3.Abs(test._fld);
+ var result = Ssse3.Abs(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new SimpleUnaryOpTest__AbsUInt32();
+
+ fixed (Vector128<Int32>* pFld1 = &test._fld1)
+ {
+ var result = Ssse3.Abs(
+ Sse2.LoadVector128((Int32*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
}
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
- var result = Ssse3.Abs(_fld);
+ var result = Ssse3.Abs(_fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(_fld, _dataTable.outArrayPtr);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
+
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ {
+ var result = Ssse3.Abs(
+ Sse2.LoadVector128((Int32*)(pFld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _dataTable.outArrayPtr);
+ }
}
public void RunStructLclFldScenario()
@@ -294,12 +429,25 @@ namespace JIT.HardwareIntrinsics.X86
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
var test = TestStruct.Create();
- var result = Ssse3.Abs(test._fld);
+ var result = Ssse3.Abs(test._fld1);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(test._fld, _dataTable.outArrayPtr);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Ssse3.Abs(
+ Sse2.LoadVector128((Int32*)(&test._fld1))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -308,6 +456,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -329,26 +485,26 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, void* result, [CallerMemberName] string method = "")
{
- Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] inArray1 = new Int32[Op1ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), firstOp);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
- private void ValidateResult(void* firstOp, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* result, [CallerMemberName] string method = "")
{
- Int32[] inArray = new Int32[Op1ElementCount];
+ Int32[] inArray1 = new Int32[Op1ElementCount];
UInt32[] outArray = new UInt32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray[0]), ref Unsafe.AsRef<byte>(firstOp), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<UInt32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<UInt32>>());
- ValidateResult(inArray, outArray, method);
+ ValidateResult(inArray1, outArray, method);
}
private void ValidateResult(Int32[] firstOp, UInt32[] result, [CallerMemberName] string method = "")
@@ -374,8 +530,8 @@ namespace JIT.HardwareIntrinsics.X86
if (!succeeded)
{
TestLibrary.TestFramework.LogInformation($"{nameof(Ssse3)}.{nameof(Ssse3.Abs)}<UInt32>(Vector128<Int32>): {method} failed:");
- TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
- TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
+ TestLibrary.TestFramework.LogInformation($" firstOp: ({string.Join(", ", firstOp)})");
+ TestLibrary.TestFramework.LogInformation($" result: ({string.Join(", ", result)})");
TestLibrary.TestFramework.LogInformation(string.Empty);
Succeeded = false;
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalAdd.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalAdd.Int16.cs
index d80968db98..0a380a8939 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalAdd.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalAdd.Int16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class HorizontalBinaryOpTest__HorizontalAddInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -115,6 +198,21 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(HorizontalBinaryOpTest__HorizontalAddInt16 testClass)
+ {
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Ssse3.HorizontalAdd(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -132,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private HorizontalBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static HorizontalBinaryOpTest__HorizontalAddInt16()
{
@@ -153,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new HorizontalBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Ssse3.IsSupported;
@@ -254,40 +352,57 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int16>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Ssse3.HorizontalAdd(
+ Sse2.LoadVector128((Int16*)(pClsVar1)),
+ Sse2.LoadVector128((Int16*)(pClsVar2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Ssse3.HorizontalAdd(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Ssse3.HorizontalAdd(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Ssse3.HorizontalAdd(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.HorizontalAdd(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Ssse3.HorizontalAdd(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.HorizontalAdd(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -301,6 +416,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new HorizontalBinaryOpTest__HorizontalAddInt16();
+
+ fixed (Vector128<Int16>* pFld1 = &test._fld1)
+ fixed (Vector128<Int16>* pFld2 = &test._fld2)
+ {
+ var result = Ssse3.HorizontalAdd(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -311,6 +445,23 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Ssse3.HorizontalAdd(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -322,6 +473,20 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Ssse3.HorizontalAdd(
+ Sse2.LoadVector128((Int16*)(&test._fld1)),
+ Sse2.LoadVector128((Int16*)(&test._fld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -330,6 +495,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -351,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalAdd.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalAdd.Int32.cs
index 6c2153bfce..1870d3b292 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalAdd.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalAdd.Int32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class HorizontalBinaryOpTest__HorizontalAddInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -115,6 +198,21 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(HorizontalBinaryOpTest__HorizontalAddInt32 testClass)
+ {
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ {
+ var result = Ssse3.HorizontalAdd(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -132,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private HorizontalBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static HorizontalBinaryOpTest__HorizontalAddInt32()
{
@@ -153,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new HorizontalBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Ssse3.IsSupported;
@@ -254,40 +352,57 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int32>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Ssse3.HorizontalAdd(
+ Sse2.LoadVector128((Int32*)(pClsVar1)),
+ Sse2.LoadVector128((Int32*)(pClsVar2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Ssse3.HorizontalAdd(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Ssse3.HorizontalAdd(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Ssse3.HorizontalAdd(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.HorizontalAdd(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Ssse3.HorizontalAdd(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.HorizontalAdd(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -301,6 +416,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new HorizontalBinaryOpTest__HorizontalAddInt32();
+
+ fixed (Vector128<Int32>* pFld1 = &test._fld1)
+ fixed (Vector128<Int32>* pFld2 = &test._fld2)
+ {
+ var result = Ssse3.HorizontalAdd(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -311,6 +445,23 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ {
+ var result = Ssse3.HorizontalAdd(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -322,6 +473,20 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Ssse3.HorizontalAdd(
+ Sse2.LoadVector128((Int32*)(&test._fld1)),
+ Sse2.LoadVector128((Int32*)(&test._fld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -330,6 +495,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -351,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalAddSaturate.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalAddSaturate.Int16.cs
index 9b3f768cec..47cf4259b3 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalAddSaturate.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalAddSaturate.Int16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class HorizontalBinaryOpTest__HorizontalAddSaturateInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -115,6 +198,21 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(HorizontalBinaryOpTest__HorizontalAddSaturateInt16 testClass)
+ {
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Ssse3.HorizontalAddSaturate(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -132,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private HorizontalBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static HorizontalBinaryOpTest__HorizontalAddSaturateInt16()
{
@@ -153,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new HorizontalBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Ssse3.IsSupported;
@@ -254,40 +352,57 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int16>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Ssse3.HorizontalAddSaturate(
+ Sse2.LoadVector128((Int16*)(pClsVar1)),
+ Sse2.LoadVector128((Int16*)(pClsVar2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Ssse3.HorizontalAddSaturate(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Ssse3.HorizontalAddSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Ssse3.HorizontalAddSaturate(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.HorizontalAddSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Ssse3.HorizontalAddSaturate(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.HorizontalAddSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -301,6 +416,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new HorizontalBinaryOpTest__HorizontalAddSaturateInt16();
+
+ fixed (Vector128<Int16>* pFld1 = &test._fld1)
+ fixed (Vector128<Int16>* pFld2 = &test._fld2)
+ {
+ var result = Ssse3.HorizontalAddSaturate(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -311,6 +445,23 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Ssse3.HorizontalAddSaturate(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -322,6 +473,20 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Ssse3.HorizontalAddSaturate(
+ Sse2.LoadVector128((Int16*)(&test._fld1)),
+ Sse2.LoadVector128((Int16*)(&test._fld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -330,6 +495,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -351,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalSubtract.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalSubtract.Int16.cs
index c5dd828bdb..80ab77a3ae 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalSubtract.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalSubtract.Int16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class HorizontalBinaryOpTest__HorizontalSubtractInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -115,6 +198,21 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(HorizontalBinaryOpTest__HorizontalSubtractInt16 testClass)
+ {
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Ssse3.HorizontalSubtract(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -132,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private HorizontalBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static HorizontalBinaryOpTest__HorizontalSubtractInt16()
{
@@ -153,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new HorizontalBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Ssse3.IsSupported;
@@ -254,40 +352,57 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int16>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Ssse3.HorizontalSubtract(
+ Sse2.LoadVector128((Int16*)(pClsVar1)),
+ Sse2.LoadVector128((Int16*)(pClsVar2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Ssse3.HorizontalSubtract(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Ssse3.HorizontalSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Ssse3.HorizontalSubtract(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.HorizontalSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Ssse3.HorizontalSubtract(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.HorizontalSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -301,6 +416,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new HorizontalBinaryOpTest__HorizontalSubtractInt16();
+
+ fixed (Vector128<Int16>* pFld1 = &test._fld1)
+ fixed (Vector128<Int16>* pFld2 = &test._fld2)
+ {
+ var result = Ssse3.HorizontalSubtract(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -311,6 +445,23 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Ssse3.HorizontalSubtract(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -322,6 +473,20 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Ssse3.HorizontalSubtract(
+ Sse2.LoadVector128((Int16*)(&test._fld1)),
+ Sse2.LoadVector128((Int16*)(&test._fld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -330,6 +495,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -351,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalSubtract.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalSubtract.Int32.cs
index 494a7490ec..d33adf0df0 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalSubtract.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalSubtract.Int32.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class HorizontalBinaryOpTest__HorizontalSubtractInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -115,6 +198,21 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(HorizontalBinaryOpTest__HorizontalSubtractInt32 testClass)
+ {
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ {
+ var result = Ssse3.HorizontalSubtract(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -132,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private HorizontalBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static HorizontalBinaryOpTest__HorizontalSubtractInt32()
{
@@ -153,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new HorizontalBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Ssse3.IsSupported;
@@ -254,40 +352,57 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int32>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int32>* pClsVar2 = &_clsVar2)
+ {
+ var result = Ssse3.HorizontalSubtract(
+ Sse2.LoadVector128((Int32*)(pClsVar1)),
+ Sse2.LoadVector128((Int32*)(pClsVar2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Ssse3.HorizontalSubtract(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Ssse3.HorizontalSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Ssse3.HorizontalSubtract(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.HorizontalSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Ssse3.HorizontalSubtract(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.HorizontalSubtract(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -301,6 +416,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new HorizontalBinaryOpTest__HorizontalSubtractInt32();
+
+ fixed (Vector128<Int32>* pFld1 = &test._fld1)
+ fixed (Vector128<Int32>* pFld2 = &test._fld2)
+ {
+ var result = Ssse3.HorizontalSubtract(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -311,6 +445,23 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int32>* pFld1 = &_fld1)
+ fixed (Vector128<Int32>* pFld2 = &_fld2)
+ {
+ var result = Ssse3.HorizontalSubtract(
+ Sse2.LoadVector128((Int32*)(pFld1)),
+ Sse2.LoadVector128((Int32*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -322,6 +473,20 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Ssse3.HorizontalSubtract(
+ Sse2.LoadVector128((Int32*)(&test._fld1)),
+ Sse2.LoadVector128((Int32*)(&test._fld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -330,6 +495,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -351,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalSubtractSaturate.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalSubtractSaturate.Int16.cs
index 6766b25b30..21bc15fa08 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalSubtractSaturate.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/HorizontalSubtractSaturate.Int16.cs
@@ -52,6 +52,12 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing a static member works
test.RunClsVarScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing a static member works, using pinning and Load
+ test.RunClsVarScenario_Load();
+ }
+
// Validates passing a local works, using Unsafe.Read
test.RunLclVarScenario_UnsafeRead();
@@ -67,14 +73,38 @@ namespace JIT.HardwareIntrinsics.X86
// Validates passing the field of a local class works
test.RunClassLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local class works, using pinning and Load
+ test.RunClassLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a class works
test.RunClassFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a class works, using pinning and Load
+ test.RunClassFldScenario_Load();
+ }
+
// Validates passing the field of a local struct works
test.RunStructLclFldScenario();
+ if (Sse2.IsSupported)
+ {
+ // Validates passing the field of a local struct works, using pinning and Load
+ test.RunStructLclFldScenario_Load();
+ }
+
// Validates passing an instance member of a struct works
test.RunStructFldScenario();
+
+ if (Sse2.IsSupported)
+ {
+ // Validates passing an instance member of a struct works, using pinning and Load
+ test.RunStructFldScenario_Load();
+ }
}
else
{
@@ -91,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class HorizontalBinaryOpTest__HorizontalSubtractSaturateInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -115,6 +198,21 @@ namespace JIT.HardwareIntrinsics.X86
Unsafe.Write(testClass._dataTable.outArrayPtr, result);
testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
}
+
+ public void RunStructFldScenario_Load(HorizontalBinaryOpTest__HorizontalSubtractSaturateInt16 testClass)
+ {
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Ssse3.HorizontalSubtractSaturate(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ Unsafe.Write(testClass._dataTable.outArrayPtr, result);
+ testClass.ValidateResult(_fld1, _fld2, testClass._dataTable.outArrayPtr);
+ }
+ }
}
private static readonly int LargestVectorSize = 16;
@@ -132,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private HorizontalBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static HorizontalBinaryOpTest__HorizontalSubtractSaturateInt16()
{
@@ -153,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new HorizontalBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Ssse3.IsSupported;
@@ -254,40 +352,57 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
}
+ public void RunClsVarScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClsVarScenario_Load));
+
+ fixed (Vector128<Int16>* pClsVar1 = &_clsVar1)
+ fixed (Vector128<Int16>* pClsVar2 = &_clsVar2)
+ {
+ var result = Ssse3.HorizontalSubtractSaturate(
+ Sse2.LoadVector128((Int16*)(pClsVar1)),
+ Sse2.LoadVector128((Int16*)(pClsVar2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_clsVar1, _clsVar2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunLclVarScenario_UnsafeRead()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Ssse3.HorizontalSubtractSaturate(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Ssse3.HorizontalSubtractSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Ssse3.HorizontalSubtractSaturate(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.HorizontalSubtractSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Ssse3.HorizontalSubtractSaturate(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.HorizontalSubtractSaturate(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -301,6 +416,25 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunClassLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassLclFldScenario_Load));
+
+ var test = new HorizontalBinaryOpTest__HorizontalSubtractSaturateInt16();
+
+ fixed (Vector128<Int16>* pFld1 = &test._fld1)
+ fixed (Vector128<Int16>* pFld2 = &test._fld2)
+ {
+ var result = Ssse3.HorizontalSubtractSaturate(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunClassFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario));
@@ -311,6 +445,23 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
}
+ public void RunClassFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunClassFldScenario_Load));
+
+ fixed (Vector128<Int16>* pFld1 = &_fld1)
+ fixed (Vector128<Int16>* pFld2 = &_fld2)
+ {
+ var result = Ssse3.HorizontalSubtractSaturate(
+ Sse2.LoadVector128((Int16*)(pFld1)),
+ Sse2.LoadVector128((Int16*)(pFld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(_fld1, _fld2, _dataTable.outArrayPtr);
+ }
+ }
+
public void RunStructLclFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario));
@@ -322,6 +473,20 @@ namespace JIT.HardwareIntrinsics.X86
ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
}
+ public void RunStructLclFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructLclFldScenario_Load));
+
+ var test = TestStruct.Create();
+ var result = Ssse3.HorizontalSubtractSaturate(
+ Sse2.LoadVector128((Int16*)(&test._fld1)),
+ Sse2.LoadVector128((Int16*)(&test._fld2))
+ );
+
+ Unsafe.Write(_dataTable.outArrayPtr, result);
+ ValidateResult(test._fld1, test._fld2, _dataTable.outArrayPtr);
+ }
+
public void RunStructFldScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario));
@@ -330,6 +495,14 @@ namespace JIT.HardwareIntrinsics.X86
test.RunStructFldScenario(this);
}
+ public void RunStructFldScenario_Load()
+ {
+ TestLibrary.TestFramework.BeginScenario(nameof(RunStructFldScenario_Load));
+
+ var test = TestStruct.Create();
+ test.RunStructFldScenario_Load(this);
+ }
+
public void RunUnsupportedScenario()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunUnsupportedScenario));
@@ -351,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/MultiplyAddAdjacent.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/MultiplyAddAdjacent.Int16.cs
index 372def13d2..697062877f 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/MultiplyAddAdjacent.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/MultiplyAddAdjacent.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyAddAdjacentInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, SByte[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Byte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyAddAdjacentInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Byte, SByte>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Ssse3.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Ssse3.MultiplyAddAdjacent(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Ssse3.MultiplyAddAdjacent(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Ssse3.MultiplyAddAdjacent(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.MultiplyAddAdjacent(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Ssse3.MultiplyAddAdjacent(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.MultiplyAddAdjacent(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/MultiplyHighRoundScale.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/MultiplyHighRoundScale.Int16.cs
index 65b3a1c0ef..8286064851 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/MultiplyHighRoundScale.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/MultiplyHighRoundScale.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__MultiplyHighRoundScaleInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__MultiplyHighRoundScaleInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Ssse3.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Ssse3.MultiplyHighRoundScale(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Ssse3.MultiplyHighRoundScale(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Ssse3.MultiplyHighRoundScale(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.MultiplyHighRoundScale(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Ssse3.MultiplyHighRoundScale(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.MultiplyHighRoundScale(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Shuffle.Byte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Shuffle.Byte.cs
index 86ccd70a2f..f0d653bedf 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Shuffle.Byte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Shuffle.Byte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__ShuffleByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Byte[] inArray1, Byte[] inArray2, Byte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Byte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Byte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Byte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Byte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Byte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Byte> _fld1;
private Vector128<Byte> _fld2;
- private SimpleBinaryOpTest__DataTable<Byte, Byte, Byte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__ShuffleByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Byte, Byte, Byte>(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Byte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Ssse3.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
- var result = Ssse3.Shuffle(left, right);
+ var op1 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Byte>>(_dataTable.inArray2Ptr);
+ var result = Ssse3.Shuffle(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Ssse3.Shuffle(left, right);
+ var op1 = Sse2.LoadVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.Shuffle(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
- var result = Ssse3.Shuffle(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Byte*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.Shuffle(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Byte> left, Vector128<Byte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Byte> op1, Vector128<Byte> op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Byte[] inArray1 = new Byte[Op1ElementCount];
Byte[] inArray2 = new Byte[Op2ElementCount];
Byte[] outArray = new Byte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Byte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Byte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Byte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Byte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Byte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Shuffle.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Shuffle.SByte.cs
index 2c084311a1..0645602e81 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Shuffle.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Shuffle.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__ShuffleSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__ShuffleSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Ssse3.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Ssse3.Shuffle(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Ssse3.Shuffle(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Ssse3.Shuffle(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.Shuffle(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Ssse3.Shuffle(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.Shuffle(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Sign.Int16.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Sign.Int16.cs
index e15034beb9..43d7759ef8 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Sign.Int16.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Sign.Int16.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SignInt16
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int16[] inArray1, Int16[] inArray2, Int16[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int16>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int16>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int16, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int16, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int16> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int16> _fld1;
private Vector128<Int16> _fld2;
- private SimpleBinaryOpTest__DataTable<Int16, Int16, Int16> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SignInt16()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt16(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt16(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int16, Int16, Int16>(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int16[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Ssse3.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
- var result = Ssse3.Sign(left, right);
+ var op1 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int16>>(_dataTable.inArray2Ptr);
+ var result = Ssse3.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Ssse3.Sign(left, right);
+ var op1 = Sse2.LoadVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
- var result = Ssse3.Sign(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int16*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int16> left, Vector128<Int16> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int16> op1, Vector128<Int16> op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int16[] inArray1 = new Int16[Op1ElementCount];
Int16[] inArray2 = new Int16[Op2ElementCount];
Int16[] outArray = new Int16[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int16>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int16>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int16>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int16, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int16>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Sign.Int32.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Sign.Int32.cs
index ee5b238df1..4b19bbfa30 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Sign.Int32.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Sign.Int32.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SignInt32
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(Int32[] inArray1, Int32[] inArray2, Int32[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<Int32>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<Int32>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<Int32, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<Int32, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<Int32> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<Int32> _fld1;
private Vector128<Int32> _fld2;
- private SimpleBinaryOpTest__DataTable<Int32, Int32, Int32> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SignInt32()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetInt32(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetInt32(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<Int32, Int32, Int32>(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new Int32[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Ssse3.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
- var result = Ssse3.Sign(left, right);
+ var op1 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<Int32>>(_dataTable.inArray2Ptr);
+ var result = Ssse3.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Ssse3.Sign(left, right);
+ var op1 = Sse2.LoadVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
- var result = Ssse3.Sign(left, right);
+ var op1 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((Int32*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<Int32> left, Vector128<Int32> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<Int32> op1, Vector128<Int32> op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
Int32[] inArray1 = new Int32[Op1ElementCount];
Int32[] inArray2 = new Int32[Op2ElementCount];
Int32[] outArray = new Int32[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<Int32>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<Int32>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<Int32>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<Int32, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<Int32>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Sign.SByte.cs b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Sign.SByte.cs
index 7d4dba40ce..371de9cb7d 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Sign.SByte.cs
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Sign.SByte.cs
@@ -121,6 +121,59 @@ namespace JIT.HardwareIntrinsics.X86
public sealed unsafe class SimpleBinaryOpTest__SignSByte
{
+ private struct DataTable
+ {
+ private byte[] inArray1;
+ private byte[] inArray2;
+ private byte[] outArray;
+
+ private GCHandle inHandle1;
+ private GCHandle inHandle2;
+ private GCHandle outHandle;
+
+ private ulong alignment;
+
+ public DataTable(SByte[] inArray1, SByte[] inArray2, SByte[] outArray, int alignment)
+ {
+ int sizeOfinArray1 = inArray1.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfinArray2 = inArray2.Length * Unsafe.SizeOf<SByte>();
+ int sizeOfoutArray = outArray.Length * Unsafe.SizeOf<SByte>();
+ if ((alignment != 32 && alignment != 16) || (alignment * 2) < sizeOfinArray1 || (alignment * 2) < sizeOfinArray2 || (alignment * 2) < sizeOfoutArray)
+ {
+ throw new ArgumentException("Invalid value of alignment");
+ }
+
+ this.inArray1 = new byte[alignment * 2];
+ this.inArray2 = new byte[alignment * 2];
+ this.outArray = new byte[alignment * 2];
+
+ this.inHandle1 = GCHandle.Alloc(this.inArray1, GCHandleType.Pinned);
+ this.inHandle2 = GCHandle.Alloc(this.inArray2, GCHandleType.Pinned);
+ this.outHandle = GCHandle.Alloc(this.outArray, GCHandleType.Pinned);
+
+ this.alignment = (ulong)alignment;
+
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray1Ptr), ref Unsafe.As<SByte, byte>(ref inArray1[0]), (uint)sizeOfinArray1);
+ Unsafe.CopyBlockUnaligned(ref Unsafe.AsRef<byte>(inArray2Ptr), ref Unsafe.As<SByte, byte>(ref inArray2[0]), (uint)sizeOfinArray2);
+ }
+
+ public void* inArray1Ptr => Align((byte*)(inHandle1.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* inArray2Ptr => Align((byte*)(inHandle2.AddrOfPinnedObject().ToPointer()), alignment);
+ public void* outArrayPtr => Align((byte*)(outHandle.AddrOfPinnedObject().ToPointer()), alignment);
+
+ public void Dispose()
+ {
+ inHandle1.Free();
+ inHandle2.Free();
+ outHandle.Free();
+ }
+
+ private static unsafe void* Align(byte* buffer, ulong expectedAlignment)
+ {
+ return (void*)(((ulong)buffer + expectedAlignment - 1) & ~(expectedAlignment - 1));
+ }
+ }
+
private struct TestStruct
{
public Vector128<SByte> _fld1;
@@ -177,7 +230,7 @@ namespace JIT.HardwareIntrinsics.X86
private Vector128<SByte> _fld1;
private Vector128<SByte> _fld2;
- private SimpleBinaryOpTest__DataTable<SByte, SByte, SByte> _dataTable;
+ private DataTable _dataTable;
static SimpleBinaryOpTest__SignSByte()
{
@@ -198,7 +251,7 @@ namespace JIT.HardwareIntrinsics.X86
for (var i = 0; i < Op1ElementCount; i++) { _data1[i] = TestLibrary.Generator.GetSByte(); }
for (var i = 0; i < Op2ElementCount; i++) { _data2[i] = TestLibrary.Generator.GetSByte(); }
- _dataTable = new SimpleBinaryOpTest__DataTable<SByte, SByte, SByte>(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
+ _dataTable = new DataTable(_data1, _data2, new SByte[RetElementCount], LargestVectorSize);
}
public bool IsSupported => Ssse3.IsSupported;
@@ -320,36 +373,36 @@ namespace JIT.HardwareIntrinsics.X86
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_UnsafeRead));
- var left = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
- var right = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
- var result = Ssse3.Sign(left, right);
+ var op1 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray1Ptr);
+ var op2 = Unsafe.Read<Vector128<SByte>>(_dataTable.inArray2Ptr);
+ var result = Ssse3.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_Load()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_Load));
- var left = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Ssse3.Sign(left, right);
+ var op1 = Sse2.LoadVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunLclVarScenario_LoadAligned()
{
TestLibrary.TestFramework.BeginScenario(nameof(RunLclVarScenario_LoadAligned));
- var left = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
- var right = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
- var result = Ssse3.Sign(left, right);
+ var op1 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray1Ptr));
+ var op2 = Sse2.LoadAlignedVector128((SByte*)(_dataTable.inArray2Ptr));
+ var result = Ssse3.Sign(op1, op2);
Unsafe.Write(_dataTable.outArrayPtr, result);
- ValidateResult(left, right, _dataTable.outArrayPtr);
+ ValidateResult(op1, op2, _dataTable.outArrayPtr);
}
public void RunClassLclFldScenario()
@@ -471,27 +524,27 @@ namespace JIT.HardwareIntrinsics.X86
}
}
- private void ValidateResult(Vector128<SByte> left, Vector128<SByte> right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(Vector128<SByte> op1, Vector128<SByte> op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), left);
- Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), right);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), op1);
+ Unsafe.WriteUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), op2);
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
}
- private void ValidateResult(void* left, void* right, void* result, [CallerMemberName] string method = "")
+ private void ValidateResult(void* op1, void* op2, void* result, [CallerMemberName] string method = "")
{
SByte[] inArray1 = new SByte[Op1ElementCount];
SByte[] inArray2 = new SByte[Op2ElementCount];
SByte[] outArray = new SByte[RetElementCount];
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(left), (uint)Unsafe.SizeOf<Vector128<SByte>>());
- Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(right), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray1[0]), ref Unsafe.AsRef<byte>(op1), (uint)Unsafe.SizeOf<Vector128<SByte>>());
+ Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref inArray2[0]), ref Unsafe.AsRef<byte>(op2), (uint)Unsafe.SizeOf<Vector128<SByte>>());
Unsafe.CopyBlockUnaligned(ref Unsafe.As<SByte, byte>(ref outArray[0]), ref Unsafe.AsRef<byte>(result), (uint)Unsafe.SizeOf<Vector128<SByte>>());
ValidateResult(inArray1, inArray2, outArray, method);
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Ssse3_r.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Ssse3_r.csproj
index ce6d17555e..c9181f0854 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Ssse3_r.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Ssse3_r.csproj
@@ -61,9 +61,7 @@
<Compile Include="Sign.Int32.cs" />
<Compile Include="Program.Ssse3.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\HorizontalBinOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>
diff --git a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Ssse3_ro.csproj b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Ssse3_ro.csproj
index 85c0755824..3c364f845b 100644
--- a/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Ssse3_ro.csproj
+++ b/tests/src/JIT/HardwareIntrinsics/X86/Ssse3/Ssse3_ro.csproj
@@ -61,9 +61,7 @@
<Compile Include="Sign.Int32.cs" />
<Compile Include="Program.Ssse3.cs" />
<Compile Include="..\Shared\Program.cs" />
- <Compile Include="..\Shared\HorizontalBinOpTest_DataTable.cs" />
<Compile Include="..\Shared\SimpleBinOpTest_DataTable.cs" />
- <Compile Include="..\Shared\SimpleUnOpTest_DataTable.cs" />
</ItemGroup>
<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory), dir.targets))\dir.targets" />
<PropertyGroup Condition=" '$(MsBuildProjectDirOverride)' != '' "></PropertyGroup>