From 908d1815abc7afbd45bccfe8a45c23fc5657eda5 Mon Sep 17 00:00:00 2001 From: Sebastian Nickolls Date: Tue, 23 Sep 2025 08:49:18 +0000 Subject: [PATCH 1/3] Map SIMD types directly from class names The current implementation derives a size based on the identified SIMD type, and then uses the size to derive the node type. It should instead directly derive the node type from the identified SIMD type, because some SIMD types will not have a statically known size, and this size may conflict with other SIMD types. --- src/coreclr/jit/compiler.h | 2 + src/coreclr/jit/gentree.cpp | 144 ++++++++++------------- src/coreclr/jit/hwintrinsic.cpp | 35 ++---- src/coreclr/jit/hwintrinsicarm64.cpp | 4 +- src/coreclr/jit/importer.cpp | 10 +- src/coreclr/jit/lclvars.cpp | 11 +- src/coreclr/jit/simd.cpp | 170 +++++++++++++++------------ 7 files changed, 183 insertions(+), 193 deletions(-) diff --git a/src/coreclr/jit/compiler.h b/src/coreclr/jit/compiler.h index 5f51bd68e138db..c8ecb1d1279106 100644 --- a/src/coreclr/jit/compiler.h +++ b/src/coreclr/jit/compiler.h @@ -9084,6 +9084,8 @@ class Compiler return isSIMDClass(clsHnd) || isHWSIMDClass(clsHnd); } + var_types getSIMDType(CORINFO_CLASS_HANDLE typeHnd, CorInfoType* baseType = nullptr); + // Get the base (element) type and size in bytes for a SIMD type. Returns CORINFO_TYPE_UNDEF // if it is not a SIMD type or is an unsupported base JIT type. CorInfoType getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeHnd, unsigned* sizeBytes = nullptr); diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index b9d49d5655f500..225208fbfa5a41 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -20962,7 +20962,7 @@ GenTreeHWIntrinsic* Compiler::gtNewSimdHWIntrinsicNode(var_types ty GenTree* Compiler::gtNewSimdAbsNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeGet() == type); @@ -21055,7 +21055,7 @@ GenTree* Compiler::gtNewSimdBinOpNode( genTreeOps op, var_types type, GenTree* op1, GenTree* op2, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); assert(varTypeIsArithmetic(simdBaseType)); @@ -21769,7 +21769,7 @@ GenTree* Compiler::gtNewSimdBinOpNode( GenTree* Compiler::gtNewSimdCeilNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -21849,7 +21849,7 @@ GenTree* Compiler::gtNewSimdCvtNode(var_types type, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -21985,7 +21985,7 @@ GenTree* Compiler::gtNewSimdCvtNativeNode(var_types type, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -22237,7 +22237,7 @@ GenTree* Compiler::gtNewSimdCmpOpNode( genTreeOps op, var_types type, GenTree* op1, GenTree* op2, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -22526,12 +22526,11 @@ GenTree* Compiler::gtNewSimdCmpOpAllNode( genTreeOps op, var_types type, GenTree* op1, GenTree* op2, CorInfoType simdBaseJitType, unsigned simdSize) { assert(type == TYP_INT); + assert(op1 != nullptr); - var_types simdType = getSIMDTypeForSize(simdSize); + var_types simdType = op1->TypeGet(); assert(varTypeIsSIMD(simdType)); - - assert(op1 != nullptr); - assert(op1->TypeIs(simdType)); + assert(genTypeSize(simdType) == simdSize); assert(op2 != nullptr); assert(op2->TypeIs(simdType)); @@ -22661,11 +22660,10 @@ GenTree* Compiler::gtNewSimdCmpOpAnyNode( { assert(type == TYP_INT); - var_types simdType = getSIMDTypeForSize(simdSize); - assert(varTypeIsSIMD(simdType)); - assert(op1 != nullptr); - assert(op1->TypeIs(simdType)); + var_types simdType = op1->TypeGet(); + assert(varTypeIsSIMD(simdType)); + assert(genTypeSize(simdType) == simdSize); assert(op2 != nullptr); assert(op2->TypeIs(simdType)); @@ -22791,7 +22789,7 @@ GenTree* Compiler::gtNewSimdCndSelNode( var_types type, GenTree* op1, GenTree* op2, GenTree* op3, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -23216,7 +23214,7 @@ GenTree* Compiler::gtNewSimdCreateSequenceNode( // is constant than there isn't any real optimization we can do and we need the full computation. assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); assert(varTypeIsArithmetic(simdBaseType)); @@ -23387,14 +23385,14 @@ GenTree* Compiler::gtNewSimdCreateSequenceNode( GenTree* Compiler::gtNewSimdDotProdNode( var_types type, GenTree* op1, GenTree* op2, CorInfoType simdBaseJitType, unsigned simdSize) { - var_types simdType = getSIMDTypeForSize(simdSize); - assert(varTypeIsSIMD(simdType)); + assert(varTypeIsSIMD(type)); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); - assert(op1->TypeIs(simdType)); + assert(op1->TypeIs(type)); assert(op2 != nullptr); - assert(op2->TypeIs(simdType)); + assert(op2->TypeIs(type)); var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); assert(varTypeIsSIMD(type)); @@ -23428,7 +23426,7 @@ GenTree* Compiler::gtNewSimdDotProdNode( GenTree* Compiler::gtNewSimdFloorNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -23473,7 +23471,7 @@ GenTree* Compiler::gtNewSimdFmaNode( var_types type, GenTree* op1, GenTree* op2, GenTree* op3, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -23588,7 +23586,7 @@ GenTree* Compiler::gtNewSimdGetElementNode( GenTree* Compiler::gtNewSimdGetIndicesNode(var_types type, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); assert(varTypeIsArithmetic(simdBaseType)); @@ -23741,7 +23739,7 @@ GenTree* Compiler::gtNewSimdIsEvenIntegerNode(var_types type, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -23768,7 +23766,7 @@ GenTree* Compiler::gtNewSimdIsEvenIntegerNode(var_types type, GenTree* Compiler::gtNewSimdIsFiniteNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -23819,7 +23817,7 @@ GenTree* Compiler::gtNewSimdIsFiniteNode(var_types type, GenTree* op1, CorInfoTy GenTree* Compiler::gtNewSimdIsInfinityNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -23850,7 +23848,7 @@ GenTree* Compiler::gtNewSimdIsInfinityNode(var_types type, GenTree* op1, CorInfo GenTree* Compiler::gtNewSimdIsIntegerNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -23890,7 +23888,7 @@ GenTree* Compiler::gtNewSimdIsIntegerNode(var_types type, GenTree* op1, CorInfoT GenTree* Compiler::gtNewSimdIsNaNNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -23921,7 +23919,7 @@ GenTree* Compiler::gtNewSimdIsNaNNode(var_types type, GenTree* op1, CorInfoType GenTree* Compiler::gtNewSimdIsNegativeNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -23963,7 +23961,7 @@ GenTree* Compiler::gtNewSimdIsNegativeInfinityNode(var_types type, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -24011,7 +24009,7 @@ GenTree* Compiler::gtNewSimdIsNegativeInfinityNode(var_types type, GenTree* Compiler::gtNewSimdIsNormalNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -24074,7 +24072,7 @@ GenTree* Compiler::gtNewSimdIsOddIntegerNode(var_types type, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -24101,7 +24099,7 @@ GenTree* Compiler::gtNewSimdIsOddIntegerNode(var_types type, GenTree* Compiler::gtNewSimdIsPositiveNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -24143,7 +24141,7 @@ GenTree* Compiler::gtNewSimdIsPositiveInfinityNode(var_types type, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -24194,7 +24192,7 @@ GenTree* Compiler::gtNewSimdIsSubnormalNode(var_types type, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -24251,7 +24249,7 @@ GenTree* Compiler::gtNewSimdIsSubnormalNode(var_types type, GenTree* Compiler::gtNewSimdIsZeroNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -24277,7 +24275,7 @@ GenTree* Compiler::gtNewSimdIsZeroNode(var_types type, GenTree* op1, CorInfoType GenTree* Compiler::gtNewSimdLoadNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); @@ -24472,7 +24470,7 @@ GenTree* Compiler::gtNewSimdMinMaxNode(var_types type, else if (!varTypeIsLong(simdBaseType)) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); } NamedIntrinsic intrinsic = NI_Illegal; @@ -25114,7 +25112,7 @@ GenTree* Compiler::gtNewSimdMinMaxNativeNode( else { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); } NamedIntrinsic intrinsic = NI_Illegal; @@ -25227,7 +25225,7 @@ GenTree* Compiler::gtNewSimdNarrowNode( var_types type, GenTree* op1, GenTree* op2, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -25699,7 +25697,7 @@ GenTree* Compiler::gtNewSimdNarrowNode( GenTree* Compiler::gtNewSimdRoundNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -25760,7 +25758,7 @@ GenTree* Compiler::gtNewSimdShuffleVariableNode( var_types type, GenTree* op1, GenTree* op2, CorInfoType simdBaseJitType, unsigned simdSize, bool isShuffleNative) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -26363,7 +26361,7 @@ GenTree* Compiler::gtNewSimdShuffleNode( var_types type, GenTree* op1, GenTree* op2, CorInfoType simdBaseJitType, unsigned simdSize, bool isShuffleNative) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -26946,7 +26944,7 @@ GenTree* Compiler::gtNewSimdShuffleNode( GenTree* Compiler::gtNewSimdSqrtNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -27004,7 +27002,7 @@ GenTree* Compiler::gtNewSimdStoreNode(GenTree* op1, GenTree* op2, CorInfoType si assert(op2 != nullptr); assert(varTypeIsSIMD(op2)); - assert(getSIMDTypeForSize(simdSize) == op2->TypeGet()); + assert(genTypeSize(op2->TypeGet()) == simdSize); var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); assert(varTypeIsArithmetic(simdBaseType)); @@ -27121,11 +27119,10 @@ GenTree* Compiler::gtNewSimdStoreNonTemporalNode(GenTree* op1, GenTree* Compiler::gtNewSimdSumNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { - var_types simdType = getSIMDTypeForSize(simdSize); - assert(varTypeIsSIMD(simdType)); - assert(op1 != nullptr); - assert(op1->TypeIs(simdType)); + var_types simdType = op1->TypeGet(); + assert(varTypeIsSIMD(simdType)); + assert(genTypeSize(simdType) == simdSize); var_types simdBaseType = JitType2PreciseVarType(simdBaseJitType); assert(varTypeIsArithmetic(simdBaseType)); @@ -27453,7 +27450,7 @@ GenTree* Compiler::gtNewSimdToScalarNode(var_types type, GenTree* op1, CorInfoTy GenTree* Compiler::gtNewSimdTruncNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -27498,7 +27495,7 @@ GenTree* Compiler::gtNewSimdUnOpNode( genTreeOps op, var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -27593,7 +27590,7 @@ GenTree* Compiler::gtNewSimdUnOpNode( GenTree* Compiler::gtNewSimdWidenLowerNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -27789,7 +27786,7 @@ GenTree* Compiler::gtNewSimdWidenLowerNode(var_types type, GenTree* op1, CorInfo GenTree* Compiler::gtNewSimdWidenUpperNode(var_types type, GenTree* op1, CorInfoType simdBaseJitType, unsigned simdSize) { assert(varTypeIsSIMD(type)); - assert(getSIMDTypeForSize(simdSize) == type); + assert(genTypeSize(type) == simdSize); assert(op1 != nullptr); assert(op1->TypeIs(type)); @@ -28115,15 +28112,15 @@ GenTreeFieldList* Compiler::gtConvertParamOpToFieldList(GenTree* op, unsigned fi unsigned fieldSize = opVarDsc->lvExactSize() / fieldCount; GenTreeFieldList* fieldList = new (this, GT_FIELD_LIST) GenTreeFieldList(); int offset = 0; - unsigned sizeBytes = 0; CORINFO_CLASS_HANDLE structType; for (unsigned fieldId = 0; fieldId < fieldCount; fieldId++) { CORINFO_FIELD_HANDLE fieldHandle = info.compCompHnd->getFieldInClass(clsHnd, fieldId); JitType2PreciseVarType(info.compCompHnd->getFieldType(fieldHandle, &structType)); - getBaseJitTypeAndSizeOfSIMDType(structType, &sizeBytes); - var_types simdType = getSIMDTypeForSize(sizeBytes); + + unsigned int size = info.compCompHnd->getClassSize(structType); + var_types simdType = getSIMDTypeForSize(size); GenTreeLclFld* fldNode = gtNewLclFldNode(lclNum, simdType, offset); fieldList->AddField(this, fldNode, offset, simdType); @@ -29663,10 +29660,8 @@ genTreeOps GenTreeHWIntrinsic::GetOperForHWIntrinsicId(NamedIntrinsic id, var_ty NamedIntrinsic GenTreeHWIntrinsic::GetHWIntrinsicIdForUnOp( Compiler* comp, genTreeOps oper, GenTree* op1, var_types simdBaseType, unsigned simdSize, bool isScalar) { - var_types simdType = comp->getSIMDTypeForSize(simdSize); assert(varTypeIsArithmetic(simdBaseType)); - assert(varTypeIsSIMD(simdType)); #if defined(TARGET_XARCH) if ((simdSize == 64) || (simdSize == 32)) @@ -29684,7 +29679,9 @@ NamedIntrinsic GenTreeHWIntrinsic::GetHWIntrinsicIdForUnOp( } assert(op1 != nullptr); - assert(op1->TypeIs(simdType)); + var_types simdType = op1->TypeGet(); + assert(varTypeIsSIMD(simdType)); + assert(genTypeSize(simdType) == simdSize); NamedIntrinsic id = NI_Illegal; @@ -29757,13 +29754,12 @@ NamedIntrinsic GenTreeHWIntrinsic::GetHWIntrinsicIdForBinOp(Compiler* comp, unsigned simdSize, bool isScalar) { - var_types simdType = comp->getSIMDTypeForSize(simdSize); - assert(varTypeIsArithmetic(simdBaseType)); - assert(varTypeIsSIMD(simdType)); assert(op1 != nullptr); - assert(op1->TypeIs(simdType)); + var_types simdType = op1->TypeGet(); + assert(varTypeIsSIMD(simdType)); + assert(genTypeSize(simdType) == simdSize); assert(op2 != nullptr); #if defined(TARGET_XARCH) @@ -30330,16 +30326,14 @@ NamedIntrinsic GenTreeHWIntrinsic::GetHWIntrinsicIdForCmpOp(Compiler* comp, bool isScalar, bool reverseCond) { - var_types simdType = comp->getSIMDTypeForSize(simdSize); + assert(op1 != nullptr); + assert(op2 != nullptr); + var_types simdType = op1->TypeGet(); + assert(genTypeSize(simdType) == simdSize); assert(varTypeIsMask(type) || (type == simdType)); - assert(varTypeIsArithmetic(simdBaseType)); assert(varTypeIsSIMD(simdType)); - assert(op1 != nullptr); - assert(op1->TypeIs(simdType)); - assert(op2 != nullptr); - #if defined(TARGET_XARCH) if (varTypeIsMask(type)) { @@ -30671,11 +30665,9 @@ NamedIntrinsic GenTreeHWIntrinsic::GetHWIntrinsicIdForCmpOp(Compiler* comp, var_types GenTreeHWIntrinsic::GetLookupTypeForCmpOp( Compiler* comp, genTreeOps oper, var_types type, var_types simdBaseType, unsigned simdSize, bool reverseCond) { - var_types simdType = comp->getSIMDTypeForSize(simdSize); - assert(varTypeIsMask(type) || (type == simdType)); - + assert(varTypeIsMask(type) || varTypeIsSIMD(type)); assert(varTypeIsArithmetic(simdBaseType)); - assert(varTypeIsSIMD(simdType)); + assert(genTypeSize(type) == simdSize); var_types lookupType = type; @@ -32516,8 +32508,6 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) case NI_Vector512_ToScalar: #endif { - var_types simdType = getSIMDTypeForSize(simdSize); - if (varTypeIsFloating(retType)) { double result = cnsNode->AsVecCon()->ToScalarFloating(simdBaseType); @@ -32777,8 +32767,6 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) break; } - var_types simdType = getSIMDTypeForSize(simdSize); - if (varTypeIsFloating(retType)) { double result = cnsNode->AsVecCon()->GetElementFloating(simdBaseType, index); @@ -33721,8 +33709,6 @@ GenTree* Compiler::gtFoldExprHWIntrinsic(GenTreeHWIntrinsic* tree) break; } - var_types simdType = getSIMDTypeForSize(simdSize); - if (varTypeIsFloating(simdBaseType)) { double value = op3->AsDblCon()->DconValue(); diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index 83909542992db3..5a4ed811abdcc1 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -1502,9 +1502,7 @@ GenTree* Compiler::getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE { if (!varTypeIsSIMD(argType)) { - unsigned int argSizeBytes; - (void)getBaseJitTypeAndSizeOfSIMDType(argClass, &argSizeBytes); - argType = getSIMDTypeForSize(argSizeBytes); + argType = getSIMDType(argClass); } assert(varTypeIsSIMD(argType)); @@ -1889,29 +1887,20 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, CorInfoType simdBaseJitType = CORINFO_TYPE_UNDEF; GenTree* retNode = nullptr; - if (retType == TYP_STRUCT) + if (retType == TYP_STRUCT && !HWIntrinsicInfo::IsMultiReg(intrinsic)) { - unsigned int sizeBytes; - simdBaseJitType = getBaseJitTypeAndSizeOfSIMDType(sig->retTypeSigClass, &sizeBytes); - - if (HWIntrinsicInfo::IsMultiReg(intrinsic)) - { - assert(sizeBytes == 0); - } + retType = impNormStructType(sig->retTypeSigClass, &simdBaseJitType); #ifdef TARGET_ARM64 - else if ((intrinsic == NI_AdvSimd_LoadAndInsertScalar) || (intrinsic == NI_AdvSimd_Arm64_LoadAndInsertScalar)) + if ((intrinsic == NI_AdvSimd_LoadAndInsertScalar) || (intrinsic == NI_AdvSimd_Arm64_LoadAndInsertScalar)) { - CorInfoType pSimdBaseJitType = CORINFO_TYPE_UNDEF; - var_types retFieldType = impNormStructType(sig->retTypeSigClass, &pSimdBaseJitType); - - if (retFieldType == TYP_STRUCT) + if (retType == TYP_STRUCT) { CORINFO_CLASS_HANDLE structType; unsigned int sizeBytes = 0; // LoadAndInsertScalar that returns 2,3 or 4 vectors - assert(pSimdBaseJitType == CORINFO_TYPE_UNDEF); + assert(simdBaseJitType == CORINFO_TYPE_UNDEF); unsigned fieldCount = info.compCompHnd->getClassNumInstanceFields(sig->retTypeSigClass); assert(fieldCount > 1); CORINFO_FIELD_HANDLE fieldHandle = info.compCompHnd->getFieldInClass(sig->retTypeClass, 0); @@ -1937,24 +1926,20 @@ GenTree* Compiler::impHWIntrinsic(NamedIntrinsic intrinsic, } else { - assert((retFieldType == TYP_SIMD8) || (retFieldType == TYP_SIMD16)); + assert((retType == TYP_SIMD8) || (retType == TYP_SIMD16)); assert(isSupportedBaseType(intrinsic, simdBaseJitType)); - retType = getSIMDTypeForSize(sizeBytes); } } -#endif else - { +#endif // We want to return early here for cases where retType was TYP_STRUCT as per method signature and // rather than deferring the decision after getting the simdBaseJitType of arg. - if (!isSupportedBaseType(intrinsic, simdBaseJitType)) + if (retType == TYP_UNDEF || !isSupportedBaseType(intrinsic, simdBaseJitType)) { return nullptr; } - assert(sizeBytes != 0); - retType = getSIMDTypeForSize(sizeBytes); - } + assert((varTypeIsSIMD(retType) || varTypeIsStruct(retType)) && isSupportedBaseType(intrinsic, simdBaseJitType)); } simdBaseJitType = getBaseJitTypeFromArgIfNeeded(intrinsic, sig, simdBaseJitType); diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index 7e73e3e2fee48c..9a89ac905074cf 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -1339,12 +1339,10 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, if (!varTypeIsLong(simdBaseType)) { - var_types simdType = getSIMDTypeForSize(simdSize); - op2 = impSIMDPopStack(); op1 = impSIMDPopStack(); - retNode = gtNewSimdDotProdNode(simdType, op1, op2, simdBaseJitType, simdSize); + retNode = gtNewSimdDotProdNode(op1->TypeGet(), op1, op2, simdBaseJitType, simdSize); retNode = gtNewSimdGetElementNode(retType, retNode, gtNewIconNode(0), simdBaseJitType, simdSize); } break; diff --git a/src/coreclr/jit/importer.cpp b/src/coreclr/jit/importer.cpp index 5d67351639e840..847c15800f9e97 100644 --- a/src/coreclr/jit/importer.cpp +++ b/src/coreclr/jit/importer.cpp @@ -1185,12 +1185,12 @@ var_types Compiler::impNormStructType(CORINFO_CLASS_HANDLE structHnd, CorInfoTyp if (structSizeMightRepresentSIMDType(originalSize)) { - unsigned int sizeBytes; - CorInfoType simdBaseJitType = getBaseJitTypeAndSizeOfSIMDType(structHnd, &sizeBytes); - if (simdBaseJitType != CORINFO_TYPE_UNDEF) + CorInfoType simdBaseJitType = CORINFO_TYPE_UNDEF; + var_types simdType = getSIMDType(structHnd, &simdBaseJitType); + if (simdBaseJitType != CORINFO_TYPE_UNDEF && simdType != TYP_UNDEF) { - assert(sizeBytes == originalSize); - structType = getSIMDTypeForSize(sizeBytes); + assert(genTypeSize(simdType) == originalSize); + structType = simdType; if (pSimdBaseJitType != nullptr) { *pSimdBaseJitType = simdBaseJitType; diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 109afd011d8190..de8be1829f7f43 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -1445,15 +1445,10 @@ var_types Compiler::StructPromotionHelper::TryPromoteValueClassAsPrimitive(CORIN #ifdef FEATURE_SIMD if (compiler->isRuntimeIntrinsicsNamespace(namespaceName) || compiler->isNumericsNamespace(namespaceName)) { - unsigned simdSize; - CorInfoType simdBaseJitType = compiler->getBaseJitTypeAndSizeOfSIMDType(node.simdTypeHnd, &simdSize); - // We will only promote fields of SIMD types that fit into a SIMD register. - if (simdBaseJitType != CORINFO_TYPE_UNDEF) + var_types type = compiler->getSIMDType(node.simdTypeHnd); + if (type != TYP_UNDEF) { - if (compiler->structSizeMightRepresentSIMDType(simdSize)) - { - return compiler->getSIMDTypeForSize(simdSize); - } + return type; } } #endif diff --git a/src/coreclr/jit/simd.cpp b/src/coreclr/jit/simd.cpp index 7fdbd76afb0081..6b1ca64d38037f 100644 --- a/src/coreclr/jit/simd.cpp +++ b/src/coreclr/jit/simd.cpp @@ -153,32 +153,21 @@ unsigned Compiler::getFFRegisterVarNum() } #endif -//---------------------------------------------------------------------------------- -// Return the base type and size of SIMD vector type given its type handle. -// -// Arguments: -// typeHnd - The handle of the type we're interested in. -// sizeBytes - out param -// -// Return Value: -// base type of SIMD vector. -// sizeBytes if non-null is set to size in bytes. -// -// Notes: -// If the size of the struct is already known call structSizeMightRepresentSIMDType -// to determine if this api needs to be called. -// -// The type handle passed here can only be used in a subset of JIT-EE calls -// since it may be called by promotion during AOT of a method that does -// not version with SPC. See CORINFO_TYPE_LAYOUT_NODE for the contract on -// the supported JIT-EE calls. -// -// TODO-Throughput: current implementation parses class name to find base type. Change -// this when we implement SIMD intrinsic identification for the final -// product. -// -CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeHnd, unsigned* sizeBytes /*= nullptr */) +var_types Compiler::getSIMDType(CORINFO_CLASS_HANDLE typeHnd, CorInfoType* baseType) { + var_types type = TYP_UNDEF; + CorInfoType simdBaseJitType = CORINFO_TYPE_UNDEF; + + if ((typeHnd == nullptr) || !isIntrinsicType(typeHnd)) + { + return TYP_UNDEF; + } + + if (baseType != nullptr) + { + *baseType = simdBaseJitType; + } + if (m_simdHandleCache == nullptr) { if (impInlineInfo == nullptr) @@ -198,23 +187,9 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH } } - if (sizeBytes != nullptr) - { - *sizeBytes = 0; - } - - if ((typeHnd == nullptr) || !isIntrinsicType(typeHnd)) - { - return CORINFO_TYPE_UNDEF; - } - const char* namespaceName; const char* className = getClassNameFromMetadata(typeHnd, &namespaceName); - // fast path search using cached type handles of important types - CorInfoType simdBaseJitType = CORINFO_TYPE_UNDEF; - unsigned size = 0; - if (isNumericsNamespace(namespaceName)) { switch (className[0]) @@ -223,14 +198,14 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH { if (strcmp(className, "Plane") != 0) { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } JITDUMP(" Known type Plane\n"); m_simdHandleCache->PlaneHandle = typeHnd; + type = TYP_SIMD16; simdBaseJitType = CORINFO_TYPE_FLOAT; - size = 4 * genTypeSize(TYP_FLOAT); break; } @@ -238,14 +213,14 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH { if (strcmp(className, "Quaternion") != 0) { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } JITDUMP(" Known type Quaternion\n"); m_simdHandleCache->QuaternionHandle = typeHnd; + type = TYP_SIMD16; simdBaseJitType = CORINFO_TYPE_FLOAT; - size = 4 * genTypeSize(TYP_FLOAT); break; } @@ -253,7 +228,7 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH { if (strncmp(className, "Vector", 6) != 0) { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } switch (className[6]) @@ -269,14 +244,14 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH { if (className[7] != '\0') { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } JITDUMP(" Found Vector2\n"); m_simdHandleCache->Vector2Handle = typeHnd; + type = TYP_SIMD8; simdBaseJitType = CORINFO_TYPE_FLOAT; - size = 2 * genTypeSize(TYP_FLOAT); break; } @@ -284,14 +259,14 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH { if (className[7] != '\0') { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } JITDUMP(" Found Vector3\n"); m_simdHandleCache->Vector3Handle = typeHnd; + type = TYP_SIMD12; simdBaseJitType = CORINFO_TYPE_FLOAT; - size = 3 * genTypeSize(TYP_FLOAT); break; } @@ -299,14 +274,14 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH { if (className[7] != '\0') { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } JITDUMP(" Found Vector4\n"); m_simdHandleCache->Vector4Handle = typeHnd; + type = TYP_SIMD16; simdBaseJitType = CORINFO_TYPE_FLOAT; - size = 4 * genTypeSize(TYP_FLOAT); break; } @@ -314,7 +289,7 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH { if ((className[7] != '1') || (className[8] != '\0')) { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } CORINFO_CLASS_HANDLE typeArgHnd = info.compCompHnd->getTypeInstantiationArgument(typeHnd, 0); @@ -322,22 +297,24 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH if ((simdBaseJitType < CORINFO_TYPE_BYTE) || (simdBaseJitType > CORINFO_TYPE_DOUBLE)) { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } JITDUMP(" Found Vector<%s>\n", varTypeName(JitType2PreciseVarType(simdBaseJitType))); - size = getVectorTByteLength(); - if (size == 0) + uint32_t vectlen = getVectorTByteLength(); + if (vectlen == 0) { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } + + type = getSIMDTypeForSize(vectlen); break; } default: { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } } break; @@ -345,14 +322,14 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH default: { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } } } #ifdef FEATURE_HW_INTRINSICS else { - size = info.compCompHnd->getClassSize(typeHnd); + unsigned int size = info.compCompHnd->getClassSize(typeHnd); switch (size) { @@ -361,7 +338,7 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH { if (strcmp(className, "Vector64`1") != 0) { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } CORINFO_CLASS_HANDLE typeArgHnd = info.compCompHnd->getTypeInstantiationArgument(typeHnd, 0); @@ -369,10 +346,11 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH if ((simdBaseJitType < CORINFO_TYPE_BYTE) || (simdBaseJitType > CORINFO_TYPE_DOUBLE)) { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } JITDUMP(" Found Vector64<%s>\n", varTypeName(JitType2PreciseVarType(simdBaseJitType))); + type = TYP_SIMD8; break; } #endif // TARGET_ARM64 @@ -381,7 +359,7 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH { if (strcmp(className, "Vector128`1") != 0) { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } CORINFO_CLASS_HANDLE typeArgHnd = info.compCompHnd->getTypeInstantiationArgument(typeHnd, 0); @@ -389,10 +367,11 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH if ((simdBaseJitType < CORINFO_TYPE_BYTE) || (simdBaseJitType > CORINFO_TYPE_DOUBLE)) { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } JITDUMP(" Found Vector128<%s>\n", varTypeName(JitType2PreciseVarType(simdBaseJitType))); + type = TYP_SIMD16; break; } @@ -401,7 +380,7 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH { if (strcmp(className, "Vector256`1") != 0) { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } CORINFO_CLASS_HANDLE typeArgHnd = info.compCompHnd->getTypeInstantiationArgument(typeHnd, 0); @@ -409,16 +388,17 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH if ((simdBaseJitType < CORINFO_TYPE_BYTE) || (simdBaseJitType > CORINFO_TYPE_DOUBLE)) { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } if (!compOpportunisticallyDependsOn(InstructionSet_AVX)) { // We must treat as a regular struct if AVX isn't supported - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } JITDUMP(" Found Vector256<%s>\n", varTypeName(JitType2PreciseVarType(simdBaseJitType))); + type = TYP_SIMD32; break; } @@ -426,7 +406,7 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH { if (strcmp(className, "Vector512`1") != 0) { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } CORINFO_CLASS_HANDLE typeArgHnd = info.compCompHnd->getTypeInstantiationArgument(typeHnd, 0); @@ -434,40 +414,84 @@ CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeH if ((simdBaseJitType < CORINFO_TYPE_BYTE) || (simdBaseJitType > CORINFO_TYPE_DOUBLE)) { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } if (!compOpportunisticallyDependsOn(InstructionSet_AVX512)) { // We must treat as a regular struct if AVX512 isn't supported - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } JITDUMP(" Found Vector512<%s>\n", varTypeName(JitType2PreciseVarType(simdBaseJitType))); + type = TYP_SIMD64; break; } #endif // TARGET_XARCH default: { - return CORINFO_TYPE_UNDEF; + return TYP_UNDEF; } } } #endif // FEATURE_HW_INTRINSICS - if (sizeBytes != nullptr) + if (baseType != nullptr) { - *sizeBytes = size; + *baseType = simdBaseJitType; } if (simdBaseJitType != CORINFO_TYPE_UNDEF) { - assert(size == info.compCompHnd->getClassSize(typeHnd)); + assert(genTypeSize(type) == info.compCompHnd->getClassSize(typeHnd)); setUsesSIMDTypes(true); } - return simdBaseJitType; + return type; +} + +//---------------------------------------------------------------------------------- +// Return the base type and size of SIMD vector type given its type handle. +// +// Arguments: +// typeHnd - The handle of the type we're interested in. +// sizeBytes - out param +// +// Return Value: +// base type of SIMD vector. +// sizeBytes if non-null is set to size in bytes. +// +// Notes: +// If the size of the struct is already known call structSizeMightRepresentSIMDType +// to determine if this api needs to be called. +// +// The type handle passed here can only be used in a subset of JIT-EE calls +// since it may be called by promotion during AOT of a method that does +// not version with SPC. See CORINFO_TYPE_LAYOUT_NODE for the contract on +// the supported JIT-EE calls. +// +// TODO-Throughput: current implementation parses class name to find base type. Change +// this when we implement SIMD intrinsic identification for the final +// product. +// +CorInfoType Compiler::getBaseJitTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeHnd, unsigned* sizeBytes /*= nullptr */) +{ + CorInfoType baseType = CORINFO_TYPE_UNDEF; + + if (sizeBytes != nullptr) + { + *sizeBytes = 0; + } + + var_types type = getSIMDType(typeHnd, &baseType); + + if (sizeBytes != nullptr && type != TYP_UNDEF) + { + *sizeBytes = genTypeSize(type); + } + + return baseType; } //------------------------------------------------------------------------ From 4466a1346c7f920905eea56d5cdb1b334ddb18ca Mon Sep 17 00:00:00 2001 From: Sebastian Nickolls Date: Mon, 10 Nov 2025 13:09:53 +0000 Subject: [PATCH 2/3] Move assertion after type resolution --- src/coreclr/jit/gentree.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 225208fbfa5a41..99e3453efc2431 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -30667,7 +30667,6 @@ var_types GenTreeHWIntrinsic::GetLookupTypeForCmpOp( { assert(varTypeIsMask(type) || varTypeIsSIMD(type)); assert(varTypeIsArithmetic(simdBaseType)); - assert(genTypeSize(type) == simdSize); var_types lookupType = type; @@ -30677,6 +30676,7 @@ var_types GenTreeHWIntrinsic::GetLookupTypeForCmpOp( lookupType = TYP_MASK; } #endif // TARGET_XARCH + assert(genTypeSize(lookupType) == simdSize); return lookupType; } From 1bf9afb74cdc7a952bb2f14ad50cc5ef5c6311c1 Mon Sep 17 00:00:00 2001 From: Sebastian Nickolls Date: Mon, 10 Nov 2025 15:44:05 +0000 Subject: [PATCH 3/3] Fix assertion logic for masks --- src/coreclr/jit/gentree.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/jit/gentree.cpp b/src/coreclr/jit/gentree.cpp index 99e3453efc2431..ea8dd6586aff3b 100644 --- a/src/coreclr/jit/gentree.cpp +++ b/src/coreclr/jit/gentree.cpp @@ -30665,7 +30665,7 @@ NamedIntrinsic GenTreeHWIntrinsic::GetHWIntrinsicIdForCmpOp(Compiler* comp, var_types GenTreeHWIntrinsic::GetLookupTypeForCmpOp( Compiler* comp, genTreeOps oper, var_types type, var_types simdBaseType, unsigned simdSize, bool reverseCond) { - assert(varTypeIsMask(type) || varTypeIsSIMD(type)); + assert(varTypeIsMask(type) || (varTypeIsSIMD(type) && (genTypeSize(type) == simdSize))); assert(varTypeIsArithmetic(simdBaseType)); var_types lookupType = type; @@ -30676,7 +30676,6 @@ var_types GenTreeHWIntrinsic::GetLookupTypeForCmpOp( lookupType = TYP_MASK; } #endif // TARGET_XARCH - assert(genTypeSize(lookupType) == simdSize); return lookupType; }