diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/vm/class.cpp | 14 | ||||
-rw-r--r-- | src/vm/methodtable.cpp | 37 | ||||
-rw-r--r-- | src/vm/methodtablebuilder.cpp | 49 |
3 files changed, 84 insertions, 16 deletions
diff --git a/src/vm/class.cpp b/src/vm/class.cpp index ea02ca7bd9..d0b07f0896 100644 --- a/src/vm/class.cpp +++ b/src/vm/class.cpp @@ -1722,6 +1722,20 @@ EEClass::CheckForHFA() if (HasExplicitFieldOffsetLayout()) return false; + // The SIMD Intrinsic types are meant to be handled specially and should not be treated as HFA + if (GetMethodTable()->IsIntrinsicType()) + { + LPCUTF8 namespaceName; + LPCUTF8 className = GetMethodTable()->GetFullyQualifiedNameInfo(&namespaceName); + + if ((strcmp(className, "Vector256`1") == 0) || (strcmp(className, "Vector128`1") == 0) || + (strcmp(className, "Vector64`1") == 0)) + { + assert(strcmp(namespaceName, "System.Runtime.Intrinsics") == 0); + return false; + } + } + CorElementType hfaType = ELEMENT_TYPE_END; FieldDesc *pFieldDescList = GetFieldDescList(); diff --git a/src/vm/methodtable.cpp b/src/vm/methodtable.cpp index 24c69cfb01..76d490d251 100644 --- a/src/vm/methodtable.cpp +++ b/src/vm/methodtable.cpp @@ -2340,6 +2340,25 @@ bool MethodTable::ClassifyEightBytesWithManagedLayout(SystemVStructRegisterPassi nestingLevel * 5, "", this->GetDebugClassName())); return false; } + + // The SIMD Intrinsic types are meant to be handled specially and should not be passed as struct registers + if (IsIntrinsicType()) + { + LPCUTF8 namespaceName; + LPCUTF8 className = GetFullyQualifiedNameInfo(&namespaceName); + + if ((strcmp(className, "Vector256`1") == 0) || (strcmp(className, "Vector128`1") == 0) || + (strcmp(className, "Vector64`1") == 0)) + { + assert(strcmp(namespaceName, "System.Runtime.Intrinsics") == 0); + + LOG((LF_JIT, LL_EVERYTHING, "%*s**** ClassifyEightBytesWithManagedLayout: struct %s is a SIMD intrinsic type; will not be enregistered\n", + nestingLevel * 5, "", this->GetDebugClassName())); + + return false; + } + } + #ifdef _DEBUG LOG((LF_JIT, LL_EVERYTHING, "%*s**** Classify %s (%p), startOffset %d, total struct size %d\n", nestingLevel * 5, "", this->GetDebugClassName(), this, startOffsetOfStruct, helperPtr->structSize)); @@ -2619,6 +2638,24 @@ bool MethodTable::ClassifyEightBytesWithNativeLayout(SystemVStructRegisterPassin return false; } + // The SIMD Intrinsic types are meant to be handled specially and should not be passed as struct registers + if (IsIntrinsicType()) + { + LPCUTF8 namespaceName; + LPCUTF8 className = GetFullyQualifiedNameInfo(&namespaceName); + + if ((strcmp(className, "Vector256`1") == 0) || (strcmp(className, "Vector128`1") == 0) || + (strcmp(className, "Vector64`1") == 0)) + { + assert(strcmp(namespaceName, "System.Runtime.Intrinsics") == 0); + + LOG((LF_JIT, LL_EVERYTHING, "%*s**** ClassifyEightBytesWithNativeLayout: struct %s is a SIMD intrinsic type; will not be enregistered\n", + nestingLevel * 5, "", this->GetDebugClassName())); + + return false; + } + } + #ifdef _DEBUG LOG((LF_JIT, LL_EVERYTHING, "%*s**** Classify for native struct %s (%p), startOffset %d, total struct size %d\n", nestingLevel * 5, "", this->GetDebugClassName(), this, startOffsetOfStruct, helperPtr->structSize)); diff --git a/src/vm/methodtablebuilder.cpp b/src/vm/methodtablebuilder.cpp index 1a6b39af5c..83116f94f5 100644 --- a/src/vm/methodtablebuilder.cpp +++ b/src/vm/methodtablebuilder.cpp @@ -1499,7 +1499,21 @@ MethodTableBuilder::BuildMethodTableThrowing( LPCUTF8 className; LPCUTF8 nameSpace; HRESULT hr = GetMDImport()->GetNameOfTypeDef(bmtInternal->pType->GetTypeDefToken(), &className, &nameSpace); - + + if (hr == S_OK && strcmp(nameSpace, "System.Runtime.Intrinsics") == 0) + { + if (IsCompilationProcess()) + { + // Disable AOT compiling for the SIMD hardware intrinsic types. These types require special + // ABI handling as they represent fundamental data types (__m64, __m128, and __m256) and not + // aggregate or union types. See https://github.com/dotnet/coreclr/issues/15943 + // + // Once they are properly handled according to the ABI requirements, we can remove this check + // and allow them to be used in crossgen/AOT scenarios. + COMPlusThrow(kTypeLoadException, IDS_EE_HWINTRINSIC_NGEN_DISALLOWED); + } + } + #if defined(_TARGET_ARM64_) // All the funtions in System.Runtime.Intrinsics.Arm.Arm64 are hardware intrinsics. if (hr == S_OK && strcmp(nameSpace, "System.Runtime.Intrinsics.Arm.Arm64") == 0) @@ -1844,6 +1858,24 @@ MethodTableBuilder::BuildMethodTableThrowing( pMT->SetIsByRefLike(); } + // If this type is marked by [Intrinsic] attribute, it may be specially treated by the runtime/compiler + // Currently, only SIMD types have [Intrinsic] attribute + // + // We check this here, before the SystemVAmd64CheckForPass[Native]StructInRegister calls to ensure the SIMD + // intrinsics are not enregistered incorrectly. + if ((GetModule()->IsSystem() || GetAssembly()->IsSIMDVectorAssembly()) && IsValueClass() && bmtGenerics->HasInstantiation()) + { + HRESULT hr = GetMDImport()->GetCustomAttributeByName(bmtInternal->pType->GetTypeDefToken(), + g_CompilerServicesIntrinsicAttribute, + NULL, + NULL); + + if (hr == S_OK) + { + pMT->SetIsIntrinsicType(); + } + } + if (IsValueClass()) { if (bmtFP->NumInstanceFieldBytes != totalDeclaredFieldSize || HasOverLayedField()) @@ -2025,21 +2057,6 @@ MethodTableBuilder::BuildMethodTableThrowing( pMT->SetICastable(); } #endif // FEATURE_ICASTABLE - - // If this type is marked by [Intrinsic] attribute, it may be specially treated by the runtime/compiler - // Currently, only SIMD types have [Intrinsic] attribute - if ((GetModule()->IsSystem() || GetAssembly()->IsSIMDVectorAssembly()) && IsValueClass() && bmtGenerics->HasInstantiation()) - { - HRESULT hr = GetMDImport()->GetCustomAttributeByName(bmtInternal->pType->GetTypeDefToken(), - g_CompilerServicesIntrinsicAttribute, - NULL, - NULL); - - if (hr == S_OK) - { - pMT->SetIsIntrinsicType(); - } - } // Grow the typedef ridmap in advance as we can't afford to // fail once we set the resolve bit |