Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit ecfe848

Browse files
Merge pull request #15942 from tannergooding/no-multireg-simd
Updating the VM to no longer treat the SIMD HWIntrinsic types as HFA or MultiReg structs
2 parents 821be4b + 4414879 commit ecfe848

File tree

3 files changed

+84
-16
lines changed

3 files changed

+84
-16
lines changed

src/vm/class.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1722,6 +1722,20 @@ EEClass::CheckForHFA()
17221722
if (HasExplicitFieldOffsetLayout())
17231723
return false;
17241724

1725+
// The SIMD Intrinsic types are meant to be handled specially and should not be treated as HFA
1726+
if (GetMethodTable()->IsIntrinsicType())
1727+
{
1728+
LPCUTF8 namespaceName;
1729+
LPCUTF8 className = GetMethodTable()->GetFullyQualifiedNameInfo(&namespaceName);
1730+
1731+
if ((strcmp(className, "Vector256`1") == 0) || (strcmp(className, "Vector128`1") == 0) ||
1732+
(strcmp(className, "Vector64`1") == 0))
1733+
{
1734+
assert(strcmp(namespaceName, "System.Runtime.Intrinsics") == 0);
1735+
return false;
1736+
}
1737+
}
1738+
17251739
CorElementType hfaType = ELEMENT_TYPE_END;
17261740

17271741
FieldDesc *pFieldDescList = GetFieldDescList();

src/vm/methodtable.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2340,6 +2340,25 @@ bool MethodTable::ClassifyEightBytesWithManagedLayout(SystemVStructRegisterPassi
23402340
nestingLevel * 5, "", this->GetDebugClassName()));
23412341
return false;
23422342
}
2343+
2344+
// The SIMD Intrinsic types are meant to be handled specially and should not be passed as struct registers
2345+
if (IsIntrinsicType())
2346+
{
2347+
LPCUTF8 namespaceName;
2348+
LPCUTF8 className = GetFullyQualifiedNameInfo(&namespaceName);
2349+
2350+
if ((strcmp(className, "Vector256`1") == 0) || (strcmp(className, "Vector128`1") == 0) ||
2351+
(strcmp(className, "Vector64`1") == 0))
2352+
{
2353+
assert(strcmp(namespaceName, "System.Runtime.Intrinsics") == 0);
2354+
2355+
LOG((LF_JIT, LL_EVERYTHING, "%*s**** ClassifyEightBytesWithManagedLayout: struct %s is a SIMD intrinsic type; will not be enregistered\n",
2356+
nestingLevel * 5, "", this->GetDebugClassName()));
2357+
2358+
return false;
2359+
}
2360+
}
2361+
23432362
#ifdef _DEBUG
23442363
LOG((LF_JIT, LL_EVERYTHING, "%*s**** Classify %s (%p), startOffset %d, total struct size %d\n",
23452364
nestingLevel * 5, "", this->GetDebugClassName(), this, startOffsetOfStruct, helperPtr->structSize));
@@ -2619,6 +2638,24 @@ bool MethodTable::ClassifyEightBytesWithNativeLayout(SystemVStructRegisterPassin
26192638
return false;
26202639
}
26212640

2641+
// The SIMD Intrinsic types are meant to be handled specially and should not be passed as struct registers
2642+
if (IsIntrinsicType())
2643+
{
2644+
LPCUTF8 namespaceName;
2645+
LPCUTF8 className = GetFullyQualifiedNameInfo(&namespaceName);
2646+
2647+
if ((strcmp(className, "Vector256`1") == 0) || (strcmp(className, "Vector128`1") == 0) ||
2648+
(strcmp(className, "Vector64`1") == 0))
2649+
{
2650+
assert(strcmp(namespaceName, "System.Runtime.Intrinsics") == 0);
2651+
2652+
LOG((LF_JIT, LL_EVERYTHING, "%*s**** ClassifyEightBytesWithNativeLayout: struct %s is a SIMD intrinsic type; will not be enregistered\n",
2653+
nestingLevel * 5, "", this->GetDebugClassName()));
2654+
2655+
return false;
2656+
}
2657+
}
2658+
26222659
#ifdef _DEBUG
26232660
LOG((LF_JIT, LL_EVERYTHING, "%*s**** Classify for native struct %s (%p), startOffset %d, total struct size %d\n",
26242661
nestingLevel * 5, "", this->GetDebugClassName(), this, startOffsetOfStruct, helperPtr->structSize));

src/vm/methodtablebuilder.cpp

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,7 +1499,21 @@ MethodTableBuilder::BuildMethodTableThrowing(
14991499
LPCUTF8 className;
15001500
LPCUTF8 nameSpace;
15011501
HRESULT hr = GetMDImport()->GetNameOfTypeDef(bmtInternal->pType->GetTypeDefToken(), &className, &nameSpace);
1502-
1502+
1503+
if (hr == S_OK && strcmp(nameSpace, "System.Runtime.Intrinsics") == 0)
1504+
{
1505+
if (IsCompilationProcess())
1506+
{
1507+
// Disable AOT compiling for the SIMD hardware intrinsic types. These types require special
1508+
// ABI handling as they represent fundamental data types (__m64, __m128, and __m256) and not
1509+
// aggregate or union types. See https://github.com/dotnet/coreclr/issues/15943
1510+
//
1511+
// Once they are properly handled according to the ABI requirements, we can remove this check
1512+
// and allow them to be used in crossgen/AOT scenarios.
1513+
COMPlusThrow(kTypeLoadException, IDS_EE_HWINTRINSIC_NGEN_DISALLOWED);
1514+
}
1515+
}
1516+
15031517
#if defined(_TARGET_ARM64_)
15041518
// All the funtions in System.Runtime.Intrinsics.Arm.Arm64 are hardware intrinsics.
15051519
if (hr == S_OK && strcmp(nameSpace, "System.Runtime.Intrinsics.Arm.Arm64") == 0)
@@ -1844,6 +1858,24 @@ MethodTableBuilder::BuildMethodTableThrowing(
18441858
pMT->SetIsByRefLike();
18451859
}
18461860

1861+
// If this type is marked by [Intrinsic] attribute, it may be specially treated by the runtime/compiler
1862+
// Currently, only SIMD types have [Intrinsic] attribute
1863+
//
1864+
// We check this here, before the SystemVAmd64CheckForPass[Native]StructInRegister calls to ensure the SIMD
1865+
// intrinsics are not enregistered incorrectly.
1866+
if ((GetModule()->IsSystem() || GetAssembly()->IsSIMDVectorAssembly()) && IsValueClass() && bmtGenerics->HasInstantiation())
1867+
{
1868+
HRESULT hr = GetMDImport()->GetCustomAttributeByName(bmtInternal->pType->GetTypeDefToken(),
1869+
g_CompilerServicesIntrinsicAttribute,
1870+
NULL,
1871+
NULL);
1872+
1873+
if (hr == S_OK)
1874+
{
1875+
pMT->SetIsIntrinsicType();
1876+
}
1877+
}
1878+
18471879
if (IsValueClass())
18481880
{
18491881
if (bmtFP->NumInstanceFieldBytes != totalDeclaredFieldSize || HasOverLayedField())
@@ -2025,21 +2057,6 @@ MethodTableBuilder::BuildMethodTableThrowing(
20252057
pMT->SetICastable();
20262058
}
20272059
#endif // FEATURE_ICASTABLE
2028-
2029-
// If this type is marked by [Intrinsic] attribute, it may be specially treated by the runtime/compiler
2030-
// Currently, only SIMD types have [Intrinsic] attribute
2031-
if ((GetModule()->IsSystem() || GetAssembly()->IsSIMDVectorAssembly()) && IsValueClass() && bmtGenerics->HasInstantiation())
2032-
{
2033-
HRESULT hr = GetMDImport()->GetCustomAttributeByName(bmtInternal->pType->GetTypeDefToken(),
2034-
g_CompilerServicesIntrinsicAttribute,
2035-
NULL,
2036-
NULL);
2037-
2038-
if (hr == S_OK)
2039-
{
2040-
pMT->SetIsIntrinsicType();
2041-
}
2042-
}
20432060

20442061
// Grow the typedef ridmap in advance as we can't afford to
20452062
// fail once we set the resolve bit

0 commit comments

Comments
 (0)