summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarol Eidt <carol.eidt@microsoft.com>2016-07-13 15:44:44 -0700
committerGitHub <noreply@github.com>2016-07-13 15:44:44 -0700
commit1a685cb47e0335ff3f7cd577cb8f0ba6ccbb8947 (patch)
tree25485d4ce0fd698794eb5b95c62f23d09399c80d /src
parentd1770839b1ab1a2dc2922c9567559cae295e61b6 (diff)
parentba66eeab4b8306ac11feb19d09c19fd2d8e5aa95 (diff)
downloadcoreclr-1a685cb47e0335ff3f7cd577cb8f0ba6ccbb8947.tar.gz
coreclr-1a685cb47e0335ff3f7cd577cb8f0ba6ccbb8947.tar.bz2
coreclr-1a685cb47e0335ff3f7cd577cb8f0ba6ccbb8947.zip
Merge pull request #6182 from wateret/fix-6051
[ARM-softfp/Linux] Get precise type for struct
Diffstat (limited to 'src')
-rw-r--r--src/jit/compiler.cpp52
-rw-r--r--src/jit/compiler.h4
-rw-r--r--src/jit/morph.cpp4
3 files changed, 59 insertions, 1 deletions
diff --git a/src/jit/compiler.cpp b/src/jit/compiler.cpp
index b7b332598f..04c90d78af 100644
--- a/src/jit/compiler.cpp
+++ b/src/jit/compiler.cpp
@@ -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:
@@ -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);
@@ -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
{
diff --git a/src/jit/compiler.h b/src/jit/compiler.h
index 26f028508d..c96defb9a7 100644
--- a/src/jit/compiler.h
+++ b/src/jit/compiler.h
@@ -1443,6 +1443,10 @@ public:
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
diff --git a/src/jit/morph.cpp b/src/jit/morph.cpp
index 12ee7791e3..c65b51b251 100644
--- a/src/jit/morph.cpp
+++ b/src/jit/morph.cpp
@@ -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