Skip to content
1 change: 1 addition & 0 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,7 @@ enum CorInfoClassId
CLASSID_STRING,
CLASSID_ARGUMENT_HANDLE,
CLASSID_RUNTIME_TYPE,
CLASSID_NUMERICS_VECTORT,
};

enum CorInfoInline
Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/inc/jiteeversionguid.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@

#include <minipal/guid.h>

constexpr GUID JITEEVersionIdentifier = { /* 65743063-e8fa-41d4-9496-c436974c00f5 */
0x65743063,
0xe8fa,
0x41d4,
{0x94, 0x96, 0xc4, 0x36, 0x97, 0x4c, 0x00, 0xf5}
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
42 changes: 39 additions & 3 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5421,6 +5421,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,
Expand Down Expand Up @@ -10222,9 +10224,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<T> for the current compilation.
// ---------------------------------------------------------------------------------------
// getCompileTimeVectorTByteLength: Get the number of bytes in a System.Numeric.Vector<T>
// 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<T>.
// Arm64: This function may return the sentinel value SIZE_UNKNOWN to indicate that the
// size of Vector<T> 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
Expand Down Expand Up @@ -10276,11 +10289,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<T> that will be used at runtime
//
// Returns:
// The size of Vector<T> 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
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31455,11 +31455,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

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/hwintrinsic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down
39 changes: 27 additions & 12 deletions src/coreclr/jit/importercalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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:
Expand Down Expand Up @@ -11266,7 +11256,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
Expand Down Expand Up @@ -12394,6 +12384,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.
//
Expand Down
3 changes: 1 addition & 2 deletions src/coreclr/jit/simd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<T>'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<T>
// length) our size can disagree with the VM's. Treat it as a regular struct then,
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/vm/jitinterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4050,6 +4050,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;
Expand Down
Loading