diff --git a/src/coreclr/jit/fgbasic.cpp b/src/coreclr/jit/fgbasic.cpp index f5b2ced1b714c..88a1b475a1074 100644 --- a/src/coreclr/jit/fgbasic.cpp +++ b/src/coreclr/jit/fgbasic.cpp @@ -1216,25 +1216,20 @@ void Compiler::fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, Fixed case NI_IsSupported_True: case NI_IsSupported_False: + case NI_IsSupported_Type: { foldableIntrinsic = true; pushedStack.PushConstant(); break; } -#if defined(TARGET_XARCH) && defined(FEATURE_HW_INTRINSICS) - case NI_Vector128_get_Count: - case NI_Vector256_get_Count: - foldableIntrinsic = true; - pushedStack.PushConstant(); - // TODO: check if it's a loop condition - we unroll such loops. - break; -#elif defined(TARGET_ARM64) && defined(FEATURE_HW_INTRINSICS) - case NI_Vector64_get_Count: - case NI_Vector128_get_Count: + + case NI_Vector_GetCount: + { foldableIntrinsic = true; pushedStack.PushConstant(); + // TODO: for FEATURE_SIMD check if it's a loop condition - we unroll such loops. break; -#endif + } default: { diff --git a/src/coreclr/jit/hwintrinsic.cpp b/src/coreclr/jit/hwintrinsic.cpp index 02e1c80811bf6..341f14a460b42 100644 --- a/src/coreclr/jit/hwintrinsic.cpp +++ b/src/coreclr/jit/hwintrinsic.cpp @@ -314,7 +314,15 @@ NamedIntrinsic HWIntrinsicInfo::lookupId(Compiler* comp, } #endif - if ((strcmp(methodName, "get_IsSupported") == 0) || isHardwareAcceleratedProp) + bool isSupportedProp = (strcmp(methodName, "get_IsSupported") == 0); + + if (isSupportedProp && (strncmp(className, "Vector", 6) == 0)) + { + // The Vector*.IsSupported props report if T is supported & is specially handled in lookupNamedIntrinsic + return NI_Illegal; + } + + if (isSupportedProp || isHardwareAcceleratedProp) { // The `compSupportsHWIntrinsic` above validates `compSupportsIsa` indicating // that the compiler can emit instructions for the ISA but not whether the diff --git a/src/coreclr/jit/hwintrinsicarm64.cpp b/src/coreclr/jit/hwintrinsicarm64.cpp index 5a7a93b6ccf79..93e36b710e065 100644 --- a/src/coreclr/jit/hwintrinsicarm64.cpp +++ b/src/coreclr/jit/hwintrinsicarm64.cpp @@ -381,6 +381,8 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector64_AsInt16: case NI_Vector64_AsInt32: case NI_Vector64_AsInt64: + case NI_Vector64_AsNInt: + case NI_Vector64_AsNUInt: case NI_Vector64_AsSByte: case NI_Vector64_AsSingle: case NI_Vector64_AsUInt16: @@ -392,6 +394,8 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_AsInt16: case NI_Vector128_AsInt32: case NI_Vector128_AsInt64: + case NI_Vector128_AsNInt: + case NI_Vector128_AsNUInt: case NI_Vector128_AsSByte: case NI_Vector128_AsSingle: case NI_Vector128_AsUInt16: @@ -399,7 +403,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_AsUInt64: case NI_Vector128_AsVector: case NI_Vector128_AsVector4: - case NI_Vector128_AsVector128: { assert(!sig->hasThis()); assert(numArgs == 1); @@ -414,6 +417,109 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } + case NI_Vector128_AsVector2: + { + assert(sig->numArgs == 1); + assert((simdSize == 16) && (simdBaseType == TYP_FLOAT)); + assert(retType == TYP_SIMD8); + + op1 = impSIMDPopStack(TYP_SIMD16); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, NI_Vector128_GetLower, simdBaseJitType, simdSize); + break; + } + + case NI_Vector128_AsVector3: + { + assert(sig->numArgs == 1); + assert((simdSize == 16) && (simdBaseType == TYP_FLOAT)); + assert(retType == TYP_SIMD12); + + op1 = impSIMDPopStack(TYP_SIMD16); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, intrinsic, simdBaseJitType, simdSize); + break; + } + + case NI_Vector128_AsVector128: + { + assert(!sig->hasThis()); + assert(numArgs == 1); + assert(retType == TYP_SIMD16); + + switch (getSIMDTypeForSize(simdSize)) + { + case TYP_SIMD8: + { + assert((simdSize == 8) && (simdBaseType == TYP_FLOAT)); + + op1 = impSIMDPopStack(TYP_SIMD8); + + if (op1->IsCnsVec()) + { + GenTreeVecCon* vecCon = op1->AsVecCon(); + vecCon->gtType = TYP_SIMD16; + + vecCon->gtSimd16Val.f32[2] = 0.0f; + vecCon->gtSimd16Val.f32[3] = 0.0f; + + return vecCon; + } + + GenTree* idx = gtNewIconNode(2, TYP_INT); + GenTree* zero = gtNewZeroConNode(TYP_FLOAT); + op1 = gtNewSimdWithElementNode(retType, op1, idx, zero, simdBaseJitType, 16, + /* isSimdAsHWIntrinsic */ false); + + idx = gtNewIconNode(3, TYP_INT); + zero = gtNewZeroConNode(TYP_FLOAT); + retNode = gtNewSimdWithElementNode(retType, op1, idx, zero, simdBaseJitType, 16, + /* isSimdAsHWIntrinsic */ false); + + break; + } + + case TYP_SIMD12: + { + assert((simdSize == 12) && (simdBaseType == TYP_FLOAT)); + + op1 = impSIMDPopStack(TYP_SIMD12); + + if (op1->IsCnsVec()) + { + GenTreeVecCon* vecCon = op1->AsVecCon(); + vecCon->gtType = TYP_SIMD16; + + vecCon->gtSimd16Val.f32[3] = 0.0f; + return vecCon; + } + + GenTree* idx = gtNewIconNode(3, TYP_INT); + GenTree* zero = gtNewZeroConNode(TYP_FLOAT); + retNode = gtNewSimdWithElementNode(retType, op1, idx, zero, simdBaseJitType, 16, + /* isSimdAsHWIntrinsic */ false); + break; + } + + case TYP_SIMD16: + { + // We fold away the cast here, as it only exists to satisfy + // the type system. It is safe to do this here since the retNode type + // and the signature return type are both the same TYP_SIMD. + + retNode = impSIMDPopStack(retType, /* expectAddr: */ false, sig->retTypeClass); + SetOpLclRelatedToSIMDIntrinsic(retNode); + assert(retNode->gtType == getSIMDTypeForSize(getSIMDTypeSizeInBytes(sig->retTypeSigClass))); + break; + } + + default: + { + unreached(); + } + } + + break; + } + case NI_Vector64_BitwiseAnd: case NI_Vector128_BitwiseAnd: case NI_Vector64_op_BitwiseAnd: @@ -743,18 +849,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } - case NI_Vector64_get_Count: - case NI_Vector128_get_Count: - { - assert(!sig->hasThis()); - assert(numArgs == 0); - - GenTreeIntCon* countNode = gtNewIconNode(getSIMDVectorLength(simdSize, simdBaseType), TYP_INT); - countNode->gtFlags |= GTF_ICON_SIMD_COUNT; - retNode = countNode; - break; - } - case NI_Vector64_Divide: case NI_Vector128_Divide: case NI_Vector64_op_Division: @@ -1738,7 +1832,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, GenTree* vectorOp = impSIMDPopStack(getSIMDTypeForSize(simdSize)); retNode = gtNewSimdWithElementNode(retType, vectorOp, indexOp, valueOp, simdBaseJitType, simdSize, - /* isSimdAsHWIntrinsic */ true); + /* isSimdAsHWIntrinsic */ false); break; } diff --git a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp index 6d9667166b545..406aa2fad5d36 100644 --- a/src/coreclr/jit/hwintrinsiccodegenarm64.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenarm64.cpp @@ -955,18 +955,27 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node) break; } + case NI_Vector128_AsVector3: + { + // AsVector3 can be a no-op when it's already in the right register, otherwise + // we just need to move the value over. Vector3 operations will themselves mask + // out the upper element when it's relevant, so it's not worth us spending extra + // cycles doing so here. + + GetEmitter()->emitIns_Mov(ins, emitSize, targetReg, op1Reg, /* canSkip */ true); + break; + } + case NI_Vector64_ToScalar: case NI_Vector128_ToScalar: { - const ssize_t indexValue = 0; - - // no-op if vector is float/double, targetReg == op1Reg and fetching for 0th index. - if ((varTypeIsFloating(intrin.baseType) && (targetReg == op1Reg) && (indexValue == 0))) + if ((varTypeIsFloating(intrin.baseType) && (targetReg == op1Reg))) { + // no-op if vector is float/double and targetReg == op1Reg break; } - GetEmitter()->emitIns_R_R_I(ins, emitTypeSize(intrin.baseType), targetReg, op1Reg, indexValue, + GetEmitter()->emitIns_R_R_I(ins, emitTypeSize(intrin.baseType), targetReg, op1Reg, /* imm */ 0, INS_OPTS_NONE); } break; diff --git a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp index ac769aeb87c3e..cb114b2d19701 100644 --- a/src/coreclr/jit/hwintrinsiccodegenxarch.cpp +++ b/src/coreclr/jit/hwintrinsiccodegenxarch.cpp @@ -1075,6 +1075,8 @@ void CodeGen::genBaseIntrinsic(GenTreeHWIntrinsic* node) break; } + case NI_Vector128_AsVector2: + case NI_Vector128_AsVector3: case NI_Vector128_ToScalar: case NI_Vector256_ToScalar: { diff --git a/src/coreclr/jit/hwintrinsiclistarm64.h b/src/coreclr/jit/hwintrinsiclistarm64.h index 123149ec38c7c..b9d1ab59b686d 100644 --- a/src/coreclr/jit/hwintrinsiclistarm64.h +++ b/src/coreclr/jit/hwintrinsiclistarm64.h @@ -24,6 +24,8 @@ HARDWARE_INTRINSIC(Vector64, AsDouble, HARDWARE_INTRINSIC(Vector64, AsInt16, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector64, AsInt32, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector64, AsInt64, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(Vector64, AsNInt, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(Vector64, AsNUInt, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector64, AsSByte, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector64, AsSingle, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector64, AsUInt16, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) @@ -50,7 +52,6 @@ HARDWARE_INTRINSIC(Vector64, EqualsAny, HARDWARE_INTRINSIC(Vector64, ExtractMostSignificantBits, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector64, Floor, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector64, get_AllBitsSet, 8, 0, {INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni}, HW_Category_Helper, HW_Flag_NoCodeGen|HW_Flag_SpecialImport) -HARDWARE_INTRINSIC(Vector64, get_Count, 8, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector64, get_One, 8, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector64, get_Zero, 8, 0, {INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi}, HW_Category_Helper, HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector64, GetElement, 8, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg) @@ -125,14 +126,18 @@ HARDWARE_INTRINSIC(Vector128, AsDouble, HARDWARE_INTRINSIC(Vector128, AsInt16, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector128, AsInt32, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector128, AsInt64, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(Vector128, AsNInt, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(Vector128, AsNUInt, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector128, AsSByte, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector128, AsSingle, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector128, AsUInt16, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector128, AsUInt32, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector128, AsUInt64, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector128, AsVector, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(Vector128, AsVector2, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(Vector128, AsVector3, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_mov, INS_invalid}, HW_Category_SIMD, HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector128, AsVector4, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) -HARDWARE_INTRINSIC(Vector128, AsVector128, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) +HARDWARE_INTRINSIC(Vector128, AsVector128, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector128, BitwiseAnd, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, BitwiseOr, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, Ceiling, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) @@ -154,7 +159,6 @@ HARDWARE_INTRINSIC(Vector128, EqualsAny, HARDWARE_INTRINSIC(Vector128, ExtractMostSignificantBits, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, Floor, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, get_AllBitsSet, 16, 0, {INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni, INS_mvni}, HW_Category_Helper, HW_Flag_NoCodeGen|HW_Flag_SpecialImport) -HARDWARE_INTRINSIC(Vector128, get_Count, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector128, get_One, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector128, get_Zero, 16, 0, {INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi, INS_movi}, HW_Category_Helper, HW_Flag_NoCodeGen|HW_Flag_SpecialImport) HARDWARE_INTRINSIC(Vector128, GetElement, 16, 2, {INS_smov, INS_umov, INS_smov, INS_umov, INS_smov, INS_umov, INS_umov, INS_umov, INS_dup, INS_dup}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg) diff --git a/src/coreclr/jit/hwintrinsiclistxarch.h b/src/coreclr/jit/hwintrinsiclistxarch.h index 013213fecbca9..8d5c2d16a35cb 100644 --- a/src/coreclr/jit/hwintrinsiclistxarch.h +++ b/src/coreclr/jit/hwintrinsiclistxarch.h @@ -36,16 +36,18 @@ HARDWARE_INTRINSIC(Vector128, AsDouble, HARDWARE_INTRINSIC(Vector128, AsInt16, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, AsInt32, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, AsInt64, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(Vector128, AsNInt, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(Vector128, AsNUInt, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, AsSByte, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, AsSingle, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, AsUInt16, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, AsUInt32, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, AsUInt64, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, AsVector, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) -HARDWARE_INTRINSIC(Vector128, AsVector2, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) -HARDWARE_INTRINSIC(Vector128, AsVector3, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(Vector128, AsVector2, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movsdsse2, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) +HARDWARE_INTRINSIC(Vector128, AsVector3, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_movups, INS_invalid}, HW_Category_SimpleSIMD, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_SpecialCodeGen) HARDWARE_INTRINSIC(Vector128, AsVector4, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) -HARDWARE_INTRINSIC(Vector128, AsVector128, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) +HARDWARE_INTRINSIC(Vector128, AsVector128, -1, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, BitwiseAnd, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, BitwiseOr, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, Ceiling, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) @@ -67,7 +69,6 @@ HARDWARE_INTRINSIC(Vector128, EqualsAny, HARDWARE_INTRINSIC(Vector128, ExtractMostSignificantBits, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, Floor, 16, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, get_AllBitsSet, 16, 0, {INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_cmpps, INS_cmpps}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_ReturnsPerElementMask) -HARDWARE_INTRINSIC(Vector128, get_Count, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, get_One, 16, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector128, get_Zero, 16, 0, {INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_ReturnsPerElementMask) HARDWARE_INTRINSIC(Vector128, GetElement, 16, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_extractps, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromFirstArg) @@ -141,6 +142,8 @@ HARDWARE_INTRINSIC(Vector256, AsDouble, HARDWARE_INTRINSIC(Vector256, AsInt16, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_AvxOnlyCompatible) HARDWARE_INTRINSIC(Vector256, AsInt32, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_AvxOnlyCompatible) HARDWARE_INTRINSIC(Vector256, AsInt64, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_AvxOnlyCompatible) +HARDWARE_INTRINSIC(Vector256, AsNInt, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_AvxOnlyCompatible) +HARDWARE_INTRINSIC(Vector256, AsNUInt, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_AvxOnlyCompatible) HARDWARE_INTRINSIC(Vector256, AsSByte, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_AvxOnlyCompatible) HARDWARE_INTRINSIC(Vector256, AsSingle, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_AvxOnlyCompatible) HARDWARE_INTRINSIC(Vector256, AsUInt16, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen|HW_Flag_AvxOnlyCompatible) @@ -169,7 +172,6 @@ HARDWARE_INTRINSIC(Vector256, EqualsAny, HARDWARE_INTRINSIC(Vector256, ExtractMostSignificantBits, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector256, Floor, 32, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_AvxOnlyCompatible) HARDWARE_INTRINSIC(Vector256, get_AllBitsSet, 32, 0, {INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_pcmpeqd, INS_cmpps, INS_cmpps}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_ReturnsPerElementMask|HW_Flag_AvxOnlyCompatible) -HARDWARE_INTRINSIC(Vector256, get_Count, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_AvxOnlyCompatible) HARDWARE_INTRINSIC(Vector256, get_One, 32, 0, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen) HARDWARE_INTRINSIC(Vector256, get_Zero, 32, 0, {INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps, INS_xorps}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_NoCodeGen|HW_Flag_ReturnsPerElementMask|HW_Flag_AvxOnlyCompatible) HARDWARE_INTRINSIC(Vector256, GetElement, 32, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_Helper, HW_Flag_SpecialImport|HW_Flag_BaseTypeFromFirstArg|HW_Flag_AvxOnlyCompatible) diff --git a/src/coreclr/jit/hwintrinsicxarch.cpp b/src/coreclr/jit/hwintrinsicxarch.cpp index af92042ce0181..a253aedc39704 100644 --- a/src/coreclr/jit/hwintrinsicxarch.cpp +++ b/src/coreclr/jit/hwintrinsicxarch.cpp @@ -576,17 +576,22 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_AsInt16: case NI_Vector128_AsInt32: case NI_Vector128_AsInt64: + case NI_Vector128_AsNInt: + case NI_Vector128_AsNUInt: case NI_Vector128_AsSByte: case NI_Vector128_AsSingle: case NI_Vector128_AsUInt16: case NI_Vector128_AsUInt32: case NI_Vector128_AsUInt64: + case NI_Vector128_AsVector4: case NI_Vector256_As: case NI_Vector256_AsByte: case NI_Vector256_AsDouble: case NI_Vector256_AsInt16: case NI_Vector256_AsInt32: case NI_Vector256_AsInt64: + case NI_Vector256_AsNInt: + case NI_Vector256_AsNUInt: case NI_Vector256_AsSByte: case NI_Vector256_AsSingle: case NI_Vector256_AsUInt16: @@ -632,28 +637,19 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, case NI_Vector128_AsVector2: case NI_Vector128_AsVector3: { - // TYP_SIMD8 and TYP_SIMD12 currently only expose "safe" versions - // which zero the upper elements and so are implemented in managed. - unreached(); - } - - case NI_Vector128_AsVector4: - { - // We fold away the cast here, as it only exists to satisfy - // the type system. It is safe to do this here since the retNode type - // and the signature return type are both the same TYP_SIMD or the - // return type is a smaller TYP_SIMD that shares the same register. - - retNode = impSIMDPopStack(retType, /* expectAddr: */ false, sig->retTypeClass); - SetOpLclRelatedToSIMDIntrinsic(retNode); - assert(retNode->gtType == getSIMDTypeForSize(getSIMDTypeSizeInBytes(sig->retTypeSigClass))); + assert(sig->numArgs == 1); + assert((simdSize == 16) && (simdBaseType == TYP_FLOAT)); + assert((retType == TYP_SIMD8) || (retType == TYP_SIMD12)); + op1 = impSIMDPopStack(TYP_SIMD16); + retNode = gtNewSimdHWIntrinsicNode(retType, op1, intrinsic, simdBaseJitType, simdSize); break; } case NI_Vector128_AsVector128: { assert(sig->numArgs == 1); + assert(retType == TYP_SIMD16); assert(HWIntrinsicInfo::BaseTypeFromFirstArg(intrinsic)); CorInfoType op1SimdBaseJitType = @@ -664,11 +660,55 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, switch (getSIMDTypeForSize(simdSize)) { case TYP_SIMD8: + { + assert((simdSize == 8) && (simdBaseType == TYP_FLOAT)); + + op1 = impSIMDPopStack(TYP_SIMD8); + + if (op1->IsCnsVec()) + { + GenTreeVecCon* vecCon = op1->AsVecCon(); + vecCon->gtType = TYP_SIMD16; + + vecCon->gtSimd16Val.f32[2] = 0.0f; + vecCon->gtSimd16Val.f32[3] = 0.0f; + + return vecCon; + } + + GenTree* idx = gtNewIconNode(2, TYP_INT); + GenTree* zero = gtNewZeroConNode(TYP_FLOAT); + op1 = gtNewSimdWithElementNode(retType, op1, idx, zero, simdBaseJitType, 16, + /* isSimdAsHWIntrinsic */ false); + + idx = gtNewIconNode(3, TYP_INT); + zero = gtNewZeroConNode(TYP_FLOAT); + retNode = gtNewSimdWithElementNode(retType, op1, idx, zero, simdBaseJitType, 16, + /* isSimdAsHWIntrinsic */ false); + + break; + } + case TYP_SIMD12: { - // TYP_SIMD8 and TYP_SIMD12 currently only expose "safe" versions - // which zero the upper elements and so are implemented in managed. - unreached(); + assert((simdSize == 12) && (simdBaseType == TYP_FLOAT)); + + op1 = impSIMDPopStack(TYP_SIMD12); + + if (op1->IsCnsVec()) + { + GenTreeVecCon* vecCon = op1->AsVecCon(); + vecCon->gtType = TYP_SIMD16; + + vecCon->gtSimd16Val.f32[3] = 0.0f; + return vecCon; + } + + GenTree* idx = gtNewIconNode(3, TYP_INT); + GenTree* zero = gtNewZeroConNode(TYP_FLOAT); + retNode = gtNewSimdWithElementNode(retType, op1, idx, zero, simdBaseJitType, 16, + /* isSimdAsHWIntrinsic */ false); + break; } case TYP_SIMD16: @@ -1357,17 +1397,6 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, break; } - case NI_Vector128_get_Count: - case NI_Vector256_get_Count: - { - assert(sig->numArgs == 0); - - GenTreeIntCon* countNode = gtNewIconNode(getSIMDVectorLength(simdSize, simdBaseType), TYP_INT); - countNode->gtFlags |= GTF_ICON_SIMD_COUNT; - retNode = countNode; - break; - } - case NI_Vector128_get_One: case NI_Vector256_get_One: { @@ -2307,7 +2336,7 @@ GenTree* Compiler::impSpecialIntrinsic(NamedIntrinsic intrinsic, GenTree* vectorOp = impSIMDPopStack(getSIMDTypeForSize(simdSize)); retNode = gtNewSimdWithElementNode(retType, vectorOp, indexOp, valueOp, simdBaseJitType, simdSize, - /* isSimdAsHWIntrinsic */ true); + /* isSimdAsHWIntrinsic */ false); break; } diff --git a/src/coreclr/jit/importercalls.cpp b/src/coreclr/jit/importercalls.cpp index 4aab1be382055..f23f08f4d5995 100644 --- a/src/coreclr/jit/importercalls.cpp +++ b/src/coreclr/jit/importercalls.cpp @@ -2359,6 +2359,76 @@ GenTree* Compiler::impIntrinsic(GenTree* newobjThis, return gtNewIconNode(false); } + if (ni == NI_IsSupported_Type) + { + CORINFO_CLASS_HANDLE typeArgHnd = info.compCompHnd->getTypeInstantiationArgument(clsHnd, 0); + CorInfoType simdBaseJitType = info.compCompHnd->getTypeForPrimitiveNumericClass(typeArgHnd); + + switch (simdBaseJitType) + { + case CORINFO_TYPE_BYTE: + case CORINFO_TYPE_UBYTE: + case CORINFO_TYPE_SHORT: + case CORINFO_TYPE_USHORT: + case CORINFO_TYPE_INT: + case CORINFO_TYPE_UINT: + case CORINFO_TYPE_LONG: + case CORINFO_TYPE_ULONG: + case CORINFO_TYPE_FLOAT: + case CORINFO_TYPE_DOUBLE: + case CORINFO_TYPE_NATIVEINT: + case CORINFO_TYPE_NATIVEUINT: + { + return gtNewIconNode(true); + } + + default: + { + return gtNewIconNode(false); + } + } + } + + if (ni == NI_Vector_GetCount) + { + CORINFO_CLASS_HANDLE typeArgHnd = info.compCompHnd->getTypeInstantiationArgument(clsHnd, 0); + CorInfoType simdBaseJitType = info.compCompHnd->getTypeForPrimitiveNumericClass(typeArgHnd); + unsigned simdSize = info.compCompHnd->getClassSize(clsHnd); + + switch (simdBaseJitType) + { + case CORINFO_TYPE_BYTE: + case CORINFO_TYPE_UBYTE: + case CORINFO_TYPE_SHORT: + case CORINFO_TYPE_USHORT: + case CORINFO_TYPE_INT: + case CORINFO_TYPE_UINT: + case CORINFO_TYPE_LONG: + case CORINFO_TYPE_ULONG: + case CORINFO_TYPE_FLOAT: + case CORINFO_TYPE_DOUBLE: + 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; + } + + default: + { + ni = NI_Throw_PlatformNotSupportedException; + break; + } + } + } + if (ni == NI_Throw_PlatformNotSupportedException) { return impUnsupportedNamedIntrinsic(CORINFO_HELP_THROW_PLATFORM_NOT_SUPPORTED, method, sig, mustExpand); @@ -7348,13 +7418,23 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) if (result == NI_Illegal) { - if (strcmp(methodName, "get_IsHardwareAccelerated") == 0) - { - // This allows the relevant code paths to be dropped as dead code even - // on platforms where FEATURE_HW_INTRINSICS is not supported. + // This allows the relevant code paths to be dropped as dead code even + // on platforms where FEATURE_HW_INTRINSICS is not supported. + if (strcmp(methodName, "get_IsSupported") == 0) + { + assert(strcmp(className, "Vector`1") == 0); + result = NI_IsSupported_Type; + } + else if (strcmp(methodName, "get_IsHardwareAccelerated") == 0) + { result = NI_IsSupported_False; } + else if (strcmp(methodName, "get_Count") == 0) + { + assert(strcmp(className, "Vector`1") == 0); + result = NI_Vector_GetCount; + } else if (gtIsRecursiveCall(method)) { // For the framework itself, any recursive intrinsics will either be @@ -7541,13 +7621,34 @@ NamedIntrinsic Compiler::lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method) if (result == NI_Illegal) { - if ((strcmp(methodName, "get_IsSupported") == 0) || (strcmp(methodName, "get_IsHardwareAccelerated") == 0)) + // This allows the relevant code paths to be dropped as dead code even + // on platforms where FEATURE_HW_INTRINSICS is not supported. + + if (strcmp(methodName, "get_IsSupported") == 0) { - // This allows the relevant code paths to be dropped as dead code even - // on platforms where FEATURE_HW_INTRINSICS is not supported. + if (strncmp(className, "Vector", 6) == 0) + { + assert((strcmp(className, "Vector64`1") == 0) || (strcmp(className, "Vector128`1") == 0) || + (strcmp(className, "Vector256`1") == 0) || (strcmp(className, "Vector512`1") == 0)); + result = NI_IsSupported_Type; + } + else + { + result = NI_IsSupported_False; + } + } + else if (strcmp(methodName, "get_IsHardwareAccelerated") == 0) + { result = NI_IsSupported_False; } + else if (strcmp(methodName, "get_Count") == 0) + { + assert((strcmp(className, "Vector64`1") == 0) || (strcmp(className, "Vector128`1") == 0) || + (strcmp(className, "Vector256`1") == 0) || (strcmp(className, "Vector512`1") == 0)); + + result = NI_Vector_GetCount; + } else if (gtIsRecursiveCall(method)) { // For the framework itself, any recursive intrinsics will either be diff --git a/src/coreclr/jit/lsraarm64.cpp b/src/coreclr/jit/lsraarm64.cpp index bb68132c80259..f8e5e2fec3548 100644 --- a/src/coreclr/jit/lsraarm64.cpp +++ b/src/coreclr/jit/lsraarm64.cpp @@ -933,17 +933,40 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou { bool simdRegToSimdRegMove = false; - if ((intrin.id == NI_Vector64_CreateScalarUnsafe) || (intrin.id == NI_Vector128_CreateScalarUnsafe)) + switch (intrin.id) { - simdRegToSimdRegMove = varTypeIsFloating(intrin.op1); - } - else if (intrin.id == NI_AdvSimd_Arm64_DuplicateToVector64) - { - simdRegToSimdRegMove = (intrin.op1->TypeGet() == TYP_DOUBLE); - } - else if ((intrin.id == NI_Vector64_ToScalar) || (intrin.id == NI_Vector128_ToScalar)) - { - simdRegToSimdRegMove = varTypeIsFloating(intrinsicTree); + case NI_Vector64_CreateScalarUnsafe: + case NI_Vector128_CreateScalarUnsafe: + { + simdRegToSimdRegMove = varTypeIsFloating(intrin.op1); + break; + } + + case NI_AdvSimd_Arm64_DuplicateToVector64: + { + simdRegToSimdRegMove = (intrin.op1->TypeGet() == TYP_DOUBLE); + break; + } + + case NI_Vector64_ToScalar: + case NI_Vector128_ToScalar: + { + simdRegToSimdRegMove = varTypeIsFloating(intrinsicTree); + break; + } + + case NI_Vector64_ToVector128Unsafe: + case NI_Vector128_AsVector3: + case NI_Vector128_GetLower: + { + simdRegToSimdRegMove = true; + break; + } + + default: + { + break; + } } // If we have an RMW intrinsic or an intrinsic with simple move semantic between two SIMD registers, diff --git a/src/coreclr/jit/lsraxarch.cpp b/src/coreclr/jit/lsraxarch.cpp index c747fddaf842e..c0fd6030c2880 100644 --- a/src/coreclr/jit/lsraxarch.cpp +++ b/src/coreclr/jit/lsraxarch.cpp @@ -2057,6 +2057,8 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree, int* pDstCou break; } + case NI_Vector128_AsVector2: + case NI_Vector128_AsVector3: case NI_Vector128_ToVector256: case NI_Vector128_ToVector256Unsafe: case NI_Vector256_GetLower: diff --git a/src/coreclr/jit/namedintrinsiclist.h b/src/coreclr/jit/namedintrinsiclist.h index c24b681b9de0d..f9c263230b7f3 100644 --- a/src/coreclr/jit/namedintrinsiclist.h +++ b/src/coreclr/jit/namedintrinsiclist.h @@ -114,7 +114,9 @@ enum NamedIntrinsic : unsigned short NI_IsSupported_True, NI_IsSupported_False, NI_IsSupported_Dynamic, + NI_IsSupported_Type, NI_Throw_PlatformNotSupportedException, + NI_Vector_GetCount, NI_System_Threading_Interlocked_And, NI_System_Threading_Interlocked_Or, diff --git a/src/coreclr/jit/simdashwintrinsic.cpp b/src/coreclr/jit/simdashwintrinsic.cpp index 5d2dbd7d52ad7..6d36289c126c4 100644 --- a/src/coreclr/jit/simdashwintrinsic.cpp +++ b/src/coreclr/jit/simdashwintrinsic.cpp @@ -737,16 +737,6 @@ GenTree* Compiler::impSimdAsHWIntrinsicSpecial(NamedIntrinsic intrinsic, return gtNewAllBitsSetConNode(retType); } - case NI_VectorT128_get_Count: -#if defined(TARGET_XARCH) - case NI_VectorT256_get_Count: -#endif // TARGET_XARCH - { - GenTreeIntCon* countNode = gtNewIconNode(getSIMDVectorLength(simdSize, simdBaseType), TYP_INT); - countNode->gtFlags |= GTF_ICON_SIMD_COUNT; - return countNode; - } - case NI_Vector2_get_One: case NI_Vector3_get_One: case NI_Vector4_get_One: diff --git a/src/coreclr/jit/simdashwintrinsiclistarm64.h b/src/coreclr/jit/simdashwintrinsiclistarm64.h index 1400eee9d366b..80e37fcaf88ef 100644 --- a/src/coreclr/jit/simdashwintrinsiclistarm64.h +++ b/src/coreclr/jit/simdashwintrinsiclistarm64.h @@ -140,7 +140,6 @@ SIMD_AS_HWINTRINSIC_ID(VectorT128, EqualsAll, SIMD_AS_HWINTRINSIC_ID(VectorT128, EqualsAny, 2, {NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT128, Floor, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT128_Floor, NI_VectorT128_Floor}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT128, get_AllBitsSet, 0, {NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC_ID(VectorT128, get_Count, 0, {NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT128, get_Item, 2, {NI_VectorT128_get_Item, NI_VectorT128_get_Item, NI_VectorT128_get_Item, NI_VectorT128_get_Item, NI_VectorT128_get_Item, NI_VectorT128_get_Item, NI_VectorT128_get_Item, NI_VectorT128_get_Item, NI_VectorT128_get_Item, NI_VectorT128_get_Item}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::BaseTypeFromThisArg) SIMD_AS_HWINTRINSIC_ID(VectorT128, get_One, 0, {NI_VectorT128_get_One, NI_VectorT128_get_One, NI_VectorT128_get_One, NI_VectorT128_get_One, NI_VectorT128_get_One, NI_VectorT128_get_One, NI_VectorT128_get_One, NI_VectorT128_get_One, NI_VectorT128_get_One, NI_VectorT128_get_One}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT128, get_Zero, 0, {NI_VectorT128_get_Zero, NI_VectorT128_get_Zero, NI_VectorT128_get_Zero, NI_VectorT128_get_Zero, NI_VectorT128_get_Zero, NI_VectorT128_get_Zero, NI_VectorT128_get_Zero, NI_VectorT128_get_Zero, NI_VectorT128_get_Zero, NI_VectorT128_get_Zero}, SimdAsHWIntrinsicFlag::None) diff --git a/src/coreclr/jit/simdashwintrinsiclistxarch.h b/src/coreclr/jit/simdashwintrinsiclistxarch.h index f500760f90a1c..24671df67296a 100644 --- a/src/coreclr/jit/simdashwintrinsiclistxarch.h +++ b/src/coreclr/jit/simdashwintrinsiclistxarch.h @@ -140,7 +140,6 @@ SIMD_AS_HWINTRINSIC_ID(VectorT128, EqualsAll, SIMD_AS_HWINTRINSIC_ID(VectorT128, EqualsAny, 2, {NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny, NI_VectorT128_EqualsAny}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT128, Floor, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT128_Floor, NI_VectorT128_Floor}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT128, get_AllBitsSet, 0, {NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet, NI_VectorT128_get_AllBitsSet}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC_ID(VectorT128, get_Count, 0, {NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count, NI_VectorT128_get_Count}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT128, get_Item, 2, {NI_VectorT128_get_Item, NI_VectorT128_get_Item, NI_VectorT128_get_Item, NI_VectorT128_get_Item, NI_VectorT128_get_Item, NI_VectorT128_get_Item, NI_VectorT128_get_Item, NI_VectorT128_get_Item, NI_VectorT128_get_Item, NI_VectorT128_get_Item}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::BaseTypeFromThisArg) SIMD_AS_HWINTRINSIC_ID(VectorT128, get_One, 0, {NI_VectorT128_get_One, NI_VectorT128_get_One, NI_VectorT128_get_One, NI_VectorT128_get_One, NI_VectorT128_get_One, NI_VectorT128_get_One, NI_VectorT128_get_One, NI_VectorT128_get_One, NI_VectorT128_get_One, NI_VectorT128_get_One}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT128, get_Zero, 0, {NI_VectorT128_get_Zero, NI_VectorT128_get_Zero, NI_VectorT128_get_Zero, NI_VectorT128_get_Zero, NI_VectorT128_get_Zero, NI_VectorT128_get_Zero, NI_VectorT128_get_Zero, NI_VectorT128_get_Zero, NI_VectorT128_get_Zero, NI_VectorT128_get_Zero}, SimdAsHWIntrinsicFlag::None) @@ -240,7 +239,6 @@ SIMD_AS_HWINTRINSIC_ID(VectorT256, EqualsAll, SIMD_AS_HWINTRINSIC_ID(VectorT256, EqualsAny, 2, {NI_VectorT256_EqualsAny, NI_VectorT256_EqualsAny, NI_VectorT256_EqualsAny, NI_VectorT256_EqualsAny, NI_VectorT256_EqualsAny, NI_VectorT256_EqualsAny, NI_VectorT256_EqualsAny, NI_VectorT256_EqualsAny, NI_VectorT256_EqualsAny, NI_VectorT256_EqualsAny}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT256, Floor, 1, {NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_Illegal, NI_VectorT256_Floor, NI_VectorT256_Floor}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT256, get_AllBitsSet, 0, {NI_VectorT256_get_AllBitsSet, NI_VectorT256_get_AllBitsSet, NI_VectorT256_get_AllBitsSet, NI_VectorT256_get_AllBitsSet, NI_VectorT256_get_AllBitsSet, NI_VectorT256_get_AllBitsSet, NI_VectorT256_get_AllBitsSet, NI_VectorT256_get_AllBitsSet, NI_VectorT256_get_AllBitsSet, NI_VectorT256_get_AllBitsSet}, SimdAsHWIntrinsicFlag::None) -SIMD_AS_HWINTRINSIC_ID(VectorT256, get_Count, 0, {NI_VectorT256_get_Count, NI_VectorT256_get_Count, NI_VectorT256_get_Count, NI_VectorT256_get_Count, NI_VectorT256_get_Count, NI_VectorT256_get_Count, NI_VectorT256_get_Count, NI_VectorT256_get_Count, NI_VectorT256_get_Count, NI_VectorT256_get_Count}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT256, get_Item, 2, {NI_VectorT256_get_Item, NI_VectorT256_get_Item, NI_VectorT256_get_Item, NI_VectorT256_get_Item, NI_VectorT256_get_Item, NI_VectorT256_get_Item, NI_VectorT256_get_Item, NI_VectorT256_get_Item, NI_VectorT256_get_Item, NI_VectorT256_get_Item}, SimdAsHWIntrinsicFlag::InstanceMethod | SimdAsHWIntrinsicFlag::BaseTypeFromThisArg) SIMD_AS_HWINTRINSIC_ID(VectorT256, get_One, 0, {NI_VectorT256_get_One, NI_VectorT256_get_One, NI_VectorT256_get_One, NI_VectorT256_get_One, NI_VectorT256_get_One, NI_VectorT256_get_One, NI_VectorT256_get_One, NI_VectorT256_get_One, NI_VectorT256_get_One, NI_VectorT256_get_One}, SimdAsHWIntrinsicFlag::None) SIMD_AS_HWINTRINSIC_ID(VectorT256, get_Zero, 0, {NI_VectorT256_get_Zero, NI_VectorT256_get_Zero, NI_VectorT256_get_Zero, NI_VectorT256_get_Zero, NI_VectorT256_get_Zero, NI_VectorT256_get_Zero, NI_VectorT256_get_Zero, NI_VectorT256_get_Zero, NI_VectorT256_get_Zero, NI_VectorT256_get_Zero}, SimdAsHWIntrinsicFlag::None) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs index 88db7bd90f960..de163d2550ee6 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128.cs @@ -237,6 +237,7 @@ public static Vector128 AsUInt64(this Vector128 vector) /// Reinterprets a as a new . /// The vector to reinterpret. /// reinterpreted as a new . + [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 AsVector128(this Vector2 value) => new Vector4(value, 0.0f, 0.0f).AsVector128(); @@ -244,6 +245,7 @@ public static Vector128 AsVector128(this Vector2 value) /// Reinterprets a as a new . /// The vector to reinterpret. /// reinterpreted as a new . + [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector128 AsVector128(this Vector3 value) => new Vector4(value, 0.0f).AsVector128(); @@ -276,6 +278,7 @@ public static Vector128 AsVector128(this Vector value) /// Reinterprets a as a new . /// The vector to reinterpret. /// reinterpreted as a new . + [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector2 AsVector2(this Vector128 value) { @@ -286,6 +289,7 @@ public static Vector2 AsVector2(this Vector128 value) /// Reinterprets a as a new . /// The vector to reinterpret. /// reinterpreted as a new . + [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] public static Vector3 AsVector3(this Vector128 value) { diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128_1.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128_1.cs index b8e80993de38d..6f3d3c0faa85e 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128_1.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector128_1.cs @@ -64,6 +64,7 @@ public static int Count /// true if is supported; otherwise, false. public static bool IsSupported { + [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] get { diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256_1.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256_1.cs index 56e19827b31b4..5ccbcadf37607 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256_1.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector256_1.cs @@ -62,6 +62,7 @@ public static int Count /// true if is supported; otherwise, false. public static bool IsSupported { + [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] get { diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512_1.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512_1.cs index 1edf3894f63d9..e7f824fcba628 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512_1.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector512_1.cs @@ -62,6 +62,7 @@ public static int Count /// true if is supported; otherwise, false. public static bool IsSupported { + [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] get { diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64_1.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64_1.cs index f2d369bcc9a47..f2ca58318fb29 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64_1.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/Vector64_1.cs @@ -70,6 +70,7 @@ public static unsafe int Count /// true if is supported; otherwise, false. public static bool IsSupported { + [Intrinsic] [MethodImpl(MethodImplOptions.AggressiveInlining)] get {