Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.
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
52 changes: 51 additions & 1 deletion src/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,49 @@ void Compiler::getStructGcPtrsFromOp(GenTreePtr op, BYTE *gcPtrsOut)
}
#endif // FEATURE_MULTIREG_ARGS

#ifdef ARM_SOFTFP
//---------------------------------------------------------------------------
// IsSingleFloat32Struct:
// Check if the given struct type contains only one float32 value type
//
// Arguments:
// clsHnd - the handle for the struct type
//
// Return Value:
// true if the given struct type contains only one float32 value type,
// false otherwise.
//

bool Compiler::isSingleFloat32Struct(CORINFO_CLASS_HANDLE clsHnd)
{
for (;;)
{
// all of class chain must be of value type and must have only one field
if (!info.compCompHnd->isValueClass(clsHnd) &&
info.compCompHnd->getClassNumInstanceFields(clsHnd) != 1)
{
return false;
}

CORINFO_CLASS_HANDLE* pClsHnd = &clsHnd;
CORINFO_FIELD_HANDLE fldHnd = info.compCompHnd->getFieldInClass(clsHnd, 0);
CorInfoType fieldType = info.compCompHnd->getFieldType(fldHnd, pClsHnd);

switch (fieldType)
{
case CORINFO_TYPE_VALUECLASS:
clsHnd = *pClsHnd;
break;

case CORINFO_TYPE_FLOAT:
return true;

default:
return false;
}
}
}
#endif // ARM_SOFTFP

//-----------------------------------------------------------------------------
// getPrimitiveTypeForStruct:
Expand Down Expand Up @@ -521,8 +564,15 @@ var_types Compiler::getPrimitiveTypeForStruct( unsigned structSize,
#endif // _TARGET_XARCH_
#endif // _TARGET_64BIT_


case TARGET_POINTER_SIZE:
#ifdef ARM_SOFTFP
// For ARM_SOFTFP, HFA is unsupported so we need to check in another way
// This matters only for size-4 struct cause bigger structs would be processed with RetBuf
if (isSingleFloat32Struct(clsHnd))
#else // !ARM_SOFTFP
if (IsHfa(clsHnd))
#endif // ARM_SOFTFP
{
#ifdef _TARGET_64BIT_
var_types hfaType = GetHfaType(clsHnd);
Expand All @@ -547,7 +597,7 @@ var_types Compiler::getPrimitiveTypeForStruct( unsigned structSize,
#else // a 32BIT target
// A structSize of 4 with IsHfa, it must be an HFA of one float
useType = TYP_FLOAT;
#endif
#endif // _TARGET_64BIT_
}
else
{
Expand Down
4 changes: 4 additions & 0 deletions src/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -1443,6 +1443,10 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
GenTreePtr impAssignMultiRegTypeToVar(GenTreePtr op, CORINFO_CLASS_HANDLE hClass);
#endif // FEATURE_MULTIREG_RET

#ifdef ARM_SOFTFP
bool isSingleFloat32Struct(CORINFO_CLASS_HANDLE hClass);
#endif // ARM_SOFTFP

//-------------------------------------------------------------------------
// Functions to handle homogeneous floating-point aggregates (HFAs) in ARM.
// HFAs are one to four element structs where each element is the same
Expand Down
4 changes: 4 additions & 0 deletions src/jit/morph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16010,7 +16010,11 @@ Compiler::fgWalkResult Compiler::fgMorphLocalField(GenTreePtr tree, fgWalkD
tree->gtLclFld.SetLclNum(fieldLclIndex);

// We need to keep the types 'compatible'. If we can switch back to a GT_LCL_VAR
#ifdef ARM_SOFTFP
assert(varTypeIsIntegralOrI(tree->TypeGet()) || varTypeIsFloating(tree->TypeGet()));
#else
assert(varTypeIsIntegralOrI(tree->TypeGet()));
#endif
if (varTypeCanReg(fldVarDsc->TypeGet()))
{
// If the type is integer-ish, then we can use it as-is
Expand Down