diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index dee4aae951532c..08f9d4b786c6bc 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -938,6 +938,7 @@ enum CorInfoClassId CLASSID_STRING, CLASSID_ARGUMENT_HANDLE, CLASSID_RUNTIME_TYPE, + CLASSID_NUMERICS_VECTORT, }; enum CorInfoInline diff --git a/src/coreclr/inc/jiteeversionguid.h b/src/coreclr/inc/jiteeversionguid.h index 7256e79b2c6b29..35e24b3d333afd 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -37,11 +37,11 @@ #include -constexpr GUID JITEEVersionIdentifier = { /* 0d18a7df-af1f-4481-a72f-aa6cf8aa0a65 */ - 0x0d18a7df, - 0xaf1f, - 0x4481, - {0xa7, 0x2f, 0xaa, 0x6c, 0xf8, 0xaa, 0x0a, 0x65} +constexpr GUID JITEEVersionIdentifier = { /* daa88390-808f-4164-908c-8635f9c8282c */ + 0xdaa88390, + 0x808f, + 0x4164, + {0x90, 0x8c, 0x86, 0x35, 0xf9, 0xc8, 0x28, 0x2c} }; #endif // JIT_EE_VERSIONING_GUID_H diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 03fa22ec8c5463..1f42fac9fbdd44 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -5527,6 +5527,8 @@ class Compiler #endif // TARGET_ARM64 #endif // FEATURE_HW_INTRINSICS + GenTree* evalVectorCount(CORINFO_CLASS_HANDLE vectorHandle, var_types simdBaseType); + GenTree* impArrayAccessIntrinsic(CORINFO_CLASS_HANDLE clsHnd, CORINFO_SIG_INFO* sig, int memberRef, @@ -10330,9 +10332,20 @@ class Compiler // Get the number of elements of baseType of SIMD vector given by its size and baseType static int getSIMDVectorLength(unsigned simdSize, var_types baseType); - // Get the number of bytes in a System.Numeric.Vector for the current compilation. + // --------------------------------------------------------------------------------------- + // getCompileTimeVectorTByteLength: Get the number of bytes in a System.Numeric.Vector + // for the current compilation, compatible with available + // InstructionSet flags. + // // Note - cannot be used for System.Runtime.Intrinsic - uint32_t getVectorTByteLength() + // + // Returns: + // The size in bytes of Vector. + // Arm64: This function may return the sentinel value SIZE_UNKNOWN to indicate that the + // size of Vector is not known at compile time. A compilation in JIT mode may + // call getRuntimeVectorTByteLength to determine the actual size instead. + // + uint32_t getCompileTimeVectorTByteLength() { // We need to report the ISA dependency to the VM so that scenarios // such as R2R work correctly for larger vector sizes, so we always @@ -10384,11 +10397,34 @@ class Compiler // TODO-WASM: Verify if we need a more complicated condition here return FP_REGSIZE_BYTES; #else - assert(!"getVectorTByteLength() unimplemented on target arch"); + assert(!"getCompileTimeVectorTByteLength() unimplemented on target arch"); unreached(); #endif } + //------------------------------------------------------------------------------------- + // getRuntimeVectorTByteLength: Get the size of Vector that will be used at runtime + // + // Returns: + // The size of Vector as resolved in EE metadata. + // + uint32_t getRuntimeVectorTByteLength() + { + uint32_t compileTimeLength = getCompileTimeVectorTByteLength(); + + if (compileTimeLength == SIZE_UNKNOWN) + { + assert(!IsAot()); + CORINFO_CLASS_HANDLE vectorT = info.compCompHnd->getBuiltinClass(CLASSID_NUMERICS_VECTORT); + assert(vectorT != NULL); + uint32_t size = info.compCompHnd->getClassSize(vectorT); + assert(size > 0); + return size; + } + + return compileTimeLength; + } + // The minimum and maximum possible number of bytes in a SIMD vector. // getMaxVectorByteLength diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index f09808f88d6f56..2b26193a63142e 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -32028,11 +32028,11 @@ ClassLayout* GenTreeHWIntrinsic::GetLayout(Compiler* compiler) const return compiler->typGetBlkLayout(64); case NI_Sve_Load2xVectorAndUnzip: - return compiler->typGetBlkLayout(compiler->getVectorTByteLength() * 2); + return compiler->typGetBlkLayout(compiler->getRuntimeVectorTByteLength() * 2); case NI_Sve_Load3xVectorAndUnzip: - return compiler->typGetBlkLayout(compiler->getVectorTByteLength() * 3); + return compiler->typGetBlkLayout(compiler->getRuntimeVectorTByteLength() * 3); case NI_Sve_Load4xVectorAndUnzip: - return compiler->typGetBlkLayout(compiler->getVectorTByteLength() * 4); + return compiler->typGetBlkLayout(compiler->getRuntimeVectorTByteLength() * 4); #endif // TARGET_ARM64 diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index a1058fbffb0ccf..f76b0394a51fc8 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -3226,7 +3226,7 @@ GenTree* Compiler::impXplatIntrinsic(NamedIntrinsic intrinsic, case NI_Vector_AsVector512: { assert(sig->numArgs == 1); - uint32_t vectorTByteLength = getVectorTByteLength(); + uint32_t vectorTByteLength = getCompileTimeVectorTByteLength(); if (vectorTByteLength == 0) { diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 19b001e5026bb2..4778636159282a 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3427,11 +3427,9 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd, { CORINFO_CLASS_HANDLE typeArgHnd; CorInfoType simdBaseJitType; - unsigned simdSize; typeArgHnd = info.compCompHnd->getTypeInstantiationArgument(clsHnd, 0); simdBaseJitType = info.compCompHnd->getTypeForPrimitiveNumericClass(typeArgHnd); - simdSize = info.compCompHnd->getClassSize(clsHnd); switch (simdBaseJitType) { @@ -3448,15 +3446,7 @@ GenTree* Compiler::impIntrinsic(CORINFO_CLASS_HANDLE clsHnd, case CORINFO_TYPE_NATIVEINT: case CORINFO_TYPE_NATIVEUINT: { - var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); - unsigned elementSize = genTypeSize(simdBaseType); - GenTreeIntCon* countNode = gtNewIconNode(simdSize / elementSize, TYP_INT); - -#if defined(FEATURE_SIMD) - countNode->gtFlags |= GTF_ICON_SIMD_COUNT; -#endif // FEATURE_SIMD - - return countNode; + return evalVectorCount(clsHnd, JitType2PreciseVarType(simdBaseJitType)); } default: @@ -11966,7 +11956,7 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) } } - uint32_t size = getVectorTByteLength(); + uint32_t size = getCompileTimeVectorTByteLength(); #ifdef TARGET_ARM64 assert((size == 16) || (size == SIZE_UNKNOWN)); #else @@ -13392,6 +13382,31 @@ GenTree* Compiler::impUnsupportedNamedIntrinsic(unsigned helper, } } +//------------------------------------------------------------------------- +// evalVectorCount: Evaluate the Count property of a vector intrinsic class using +// EE metadata. +// +// Arguments: +// vectorHandle -- handle to the vector class to query for size +// simdBaseType -- base type, whose size to use as the divisor +// +// Returns: +// The number of elements in the vector with this base type, expressed as a constant +// signed integer IR node. +GenTree* Compiler::evalVectorCount(CORINFO_CLASS_HANDLE vectorHandle, var_types simdBaseType) +{ + unsigned simdSize = info.compCompHnd->getClassSize(vectorHandle); + + unsigned elementSize = genTypeSize(simdBaseType); + GenTreeIntCon* countNode = gtNewIconNode(simdSize / elementSize, TYP_INT); + +#if defined(FEATURE_SIMD) + countNode->gtFlags |= GTF_ICON_SIMD_COUNT; +#endif // FEATURE_SIMD + + return countNode; +} + //------------------------------------------------------------------------ // impArrayAccessIntrinsic: try to replace a multi-dimensional array intrinsics with IR nodes. // diff --git a/src/coreclr/jit/simd.cpp b/src/coreclr/jit/simd.cpp index 8997b8bba33dcf..49f53e9d3dfe40 100644 --- a/src/coreclr/jit/simd.cpp +++ b/src/coreclr/jit/simd.cpp @@ -308,13 +308,12 @@ var_types Compiler::getBaseTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeHnd, u } JITDUMP(" Found Vector<%s>\n", varTypeName(simdBaseType)); - size = getVectorTByteLength(); + size = getCompileTimeVectorTByteLength(); if (size == 0) { return TYP_UNDEF; } - // Vector's length is target-dependent, so under a cross-targeting altjit (e.g. // SuperPMI replaying a context captured for a target with a different Vector // length) our size can disagree with the VM's. Treat it as a regular struct then, diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs index bc751725af3133..877eaa46c42587 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs @@ -3055,6 +3055,9 @@ private CorInfoInitClassResult initClass(CORINFO_FIELD_STRUCT_* field, CORINFO_M case CorInfoClassId.CLASSID_RUNTIME_TYPE: return ObjectToHandle(_compilation.TypeSystemContext.SystemModule.GetKnownType("System"u8, "RuntimeType"u8)); + case CorInfoClassId.CLASSID_NUMERICS_VECTORT: + return ObjectToHandle(_compilation.TypeSystemContext.SystemModule.GetKnownType("System.Numerics"u8, "Vector`1"u8)); + default: throw new NotImplementedException(); } diff --git a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs index 3ffc55a2b2d7f0..f6a86b41ee9c60 100644 --- a/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs +++ b/src/coreclr/tools/Common/JitInterface/CorInfoTypes.cs @@ -549,6 +549,7 @@ public enum CorInfoClassId CLASSID_STRING, CLASSID_ARGUMENT_HANDLE, CLASSID_RUNTIME_TYPE, + CLASSID_NUMERICS_VECTORT, } public enum CorInfoInline { diff --git a/src/coreclr/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 8fc64fc082d3b1..17ae6676165630 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -4097,6 +4097,9 @@ CORINFO_CLASS_HANDLE CEEInfo::getBuiltinClass(CorInfoClassId classId) case CLASSID_RUNTIME_TYPE: result = CORINFO_CLASS_HANDLE(g_pRuntimeTypeClass); break; + case CLASSID_NUMERICS_VECTORT: + result = CORINFO_CLASS_HANDLE(CoreLibBinder::GetClass(CLASS__VECTORT)); + break; default: _ASSERTE(!"NYI: unknown classId"); break;