diff --git a/src/coreclr/inc/corinfo.h b/src/coreclr/inc/corinfo.h index 649c467d7ec5a8..ceb89a25ae05ef 100644 --- a/src/coreclr/inc/corinfo.h +++ b/src/coreclr/inc/corinfo.h @@ -936,6 +936,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 f2bb33c42ef99e..35e24b3d333afd 100644 --- a/src/coreclr/inc/jiteeversionguid.h +++ b/src/coreclr/inc/jiteeversionguid.h @@ -37,11 +37,11 @@ #include -constexpr GUID JITEEVersionIdentifier = { /* 12e9a95b-fa7c-43ed-a339-fbbc6e74bffa */ - 0x12e9a95b, - 0xfa7c, - 0x43ed, - {0xa3, 0x39, 0xfb, 0xbc, 0x6e, 0x74, 0xbf, 0xfa} +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 54b7f1eb232b22..60dc8125b47b22 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -5441,6 +5441,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, @@ -10230,9 +10232,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 @@ -10284,11 +10297,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 8a32c07e081d46..a724749ac7c957 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -31921,11 +31921,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 0aa3dda05359a7..aa8d7b121ad0f2 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -3208,7 +3208,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 b7c0feca6df7cb..c9aca8c4bd9924 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -3310,11 +3310,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) { @@ -3331,15 +3329,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: @@ -11368,7 +11358,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 @@ -12512,6 +12502,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/vm/jitinterface.cpp b/src/coreclr/vm/jitinterface.cpp index 79e6c7f53327cb..dfa91810471220 100644 --- a/src/coreclr/vm/jitinterface.cpp +++ b/src/coreclr/vm/jitinterface.cpp @@ -4048,6 +4048,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;