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

Updating the VM to no longer treat the SIMD HWIntrinsic types as HFA or MultiReg structs #15942

Merged
merged 2 commits into from
Jan 22, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/vm/class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
37 changes: 37 additions & 0 deletions src/vm/methodtable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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));
Expand Down
49 changes: 33 additions & 16 deletions src/vm/methodtablebuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -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
Expand Down