[ARM/Linux] Fix HFA structs
authorHanjoung Lee <hanjoung.lee@samsung.com>
Fri, 19 Aug 2016 07:32:00 +0000 (16:32 +0900)
committerHanjoung Lee <hanjoung.lee@samsung.com>
Mon, 22 Aug 2016 01:35:34 +0000 (10:35 +0900)
Re-enable FEATURE_MULTIREG_RET for ARM32 which was disabled by dotnet/coreclr#6467.

Fix dotnet/coreclr#6677

Commit migrated from https://github.com/dotnet/coreclr/commit/400dee451355e92f604934479f0df75c20005604

src/coreclr/src/jit/gcencode.cpp
src/coreclr/src/jit/importer.cpp
src/coreclr/src/jit/morph.cpp
src/coreclr/src/jit/target.h

index c13754d..fbd51bb 100644 (file)
@@ -3545,7 +3545,7 @@ void GCInfo::gcInfoBlockHdrSave(GcInfoEncoder* gcInfoEncoder, unsigned methodSiz
         case TYP_STRUCT:
         {
             CORINFO_CLASS_HANDLE structType = compiler->info.compMethodInfo->args.retTypeClass;
-            if (compiler->IsMultiRegReturnedType(structType))
+            if (compiler->IsMultiRegReturnedType(structType) && !compiler->IsHfa(structType))
             {
                 BYTE gcPtrs[2] = {TYPE_GC_NONE, TYPE_GC_NONE};
                 compiler->info.compCompHnd->getClassGClayout(structType, gcPtrs);
index 6157611..ae24bb4 100644 (file)
@@ -7551,7 +7551,11 @@ GenTreePtr Compiler::impFixupCallStructReturn(GenTreePtr call, CORINFO_CLASS_HAN
             return call;
         }
 
-        return impAssignMultiRegTypeToVar(call, retClsHnd);
+        unsigned retRegCount = retTypeDesc->GetReturnRegCount();
+        if (retRegCount >= 2)
+        {
+            return impAssignMultiRegTypeToVar(call, retClsHnd);
+        }
     }
 #endif // _TARGET_ARM_
 
@@ -7689,7 +7693,7 @@ GenTreePtr Compiler::impFixupStructReturnType(GenTreePtr op, CORINFO_CLASS_HANDL
 
 #elif FEATURE_MULTIREG_RET && defined(_TARGET_ARM_)
 
-    if (!info.compIsVarArgs && IsHfa(retClsHnd))
+    if (varTypeIsStruct(info.compRetNativeType) && !info.compIsVarArgs && IsHfa(retClsHnd))
     {
         if (op->gtOper == GT_LCL_VAR)
         {
index 277c375..3bb8965 100755 (executable)
@@ -16652,7 +16652,7 @@ Compiler::fgWalkResult Compiler::fgMorphLocalField(GenTreePtr tree, fgWalkData*
             // We need to keep the types 'compatible'.  If we can switch back to a GT_LCL_VAR
             CLANG_FORMAT_COMMENT_ANCHOR;
 
-#ifdef ARM_SOFTFP
+#ifdef _TARGET_ARM_
             assert(varTypeIsIntegralOrI(tree->TypeGet()) || varTypeIsFloating(tree->TypeGet()));
 #else
             assert(varTypeIsIntegralOrI(tree->TypeGet()));
index 6413e08..2cebb5d 100644 (file)
@@ -1172,7 +1172,7 @@ typedef unsigned short regPairNoSmall; // arm: need 12 bits
   #define FEATURE_SET_FLAGS        1       // Set to true to force the JIT to mark the trees with GTF_SET_FLAGS when the flags need to be set
   #define FEATURE_MULTIREG_ARGS_OR_RET  1  // Support for passing and/or returning single values in more than one register (including HFA support)
   #define FEATURE_MULTIREG_ARGS         1  // Support for passing a single argument in more than one register (including passing HFAs)
-  #define FEATURE_MULTIREG_RET          0  // Support for returning a single value in more than one register (including HFA returns)
+  #define FEATURE_MULTIREG_RET          1  // Support for returning a single value in more than one register (including HFA returns)
   #define FEATURE_STRUCT_CLASSIFIER     0  // Uses a classifier function to determine is structs are passed/returned in more than one register
   #define MAX_PASS_MULTIREG_BYTES      32  // Maximum size of a struct that could be passed in more than one register (Max is an HFA of 4 doubles)
   #define MAX_RET_MULTIREG_BYTES       32  // Maximum size of a struct that could be returned in more than one register (Max is an HFA of 4 doubles)