Fix for issue 5795
authorBrian Sullivan <briansul@microsoft.com>
Thu, 16 Jun 2016 17:06:55 +0000 (10:06 -0700)
committerBrian Sullivan <briansul@microsoft.com>
Fri, 17 Jun 2016 18:37:50 +0000 (11:37 -0700)
We incorrectly pass the ret buf arg in x9 instead of x8

It is required that we call SortArgs and EvalArgsToTemps whenever we have any register arguments
We were not doing that when we only had a retBufArg argument in x8.

Fix for UNIX_AMD64 structs

Commit migrated from https://github.com/dotnet/coreclr/commit/0809be00850fec3eca9a968d36750fc44d69e2f3

src/coreclr/src/jit/compiler.h
src/coreclr/src/jit/morph.cpp

index c93f565..e38a31f 100644 (file)
@@ -1174,6 +1174,8 @@ class  fgArgInfo
     unsigned              stkLevel;     // Stack depth when we make this call (for x86)
 
     unsigned              argTableSize; // size of argTable array (equal to the argCount when done with fgMorphArgs)
+    bool                  hasRegArgs;   // true if we have one or more register arguments
+    bool                  hasStackArgs; // true if we have one or more stack arguments
     bool                  argsComplete; // marker for state
     bool                  argsSorted;   // marker for state
     fgArgTabEntryPtr *    argTable;     // variable sized array of per argument descrption: (i.e. argTable[argTableSize])
@@ -1247,6 +1249,8 @@ public:
     unsigned            ArgCount ()      { return argCount; }
     fgArgTabEntryPtr *  ArgTable ()      { return argTable; }
     unsigned            GetNextSlotNum() { return nextSlotNum; }
+    bool                HasRegArgs()     { return hasRegArgs; } 
+    bool                HasStackArgs()   { return hasStackArgs; }
 
 };
 
index 39e0239..98b3a43 100644 (file)
@@ -809,6 +809,9 @@ fgArgInfo::fgArgInfo(Compiler *  comp,  GenTreePtr  call, unsigned numArgs)
     nextSlotNum  = INIT_ARG_STACK_SLOT;
     stkLevel     = 0;
     argTableSize = numArgs; // the allocated table size
+
+    hasRegArgs   = false;
+    hasStackArgs = false;
     argsComplete = false;
     argsSorted   = false;
 
@@ -1041,6 +1044,7 @@ fgArgTabEntryPtr fgArgInfo::AddRegArg(unsigned    argNum,
     curArgTabEntry->isBackFilled =      false;
     curArgTabEntry->isNonStandard =     false;
 
+    hasRegArgs = true;
     AddArg(curArgTabEntry);
     return curArgTabEntry;
 }
@@ -1115,6 +1119,7 @@ fgArgTabEntryPtr fgArgInfo::AddStkArg(unsigned    argNum,
     curArgTabEntry->isBackFilled  = false;
     curArgTabEntry->isNonStandard = false;
 
+    hasStackArgs = true;
     AddArg(curArgTabEntry);
 
     nextSlotNum += numSlots;
@@ -2561,7 +2566,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
     bool            callIsVararg      = call->IsVarargs();
 #endif
 
-    bool hasNonStandardArg = false;
 #ifndef LEGACY_BACKEND
     // data structure for keeping track of non-standard args we insert
     // (args that have a special meaning and are not passed following the normal
@@ -3707,7 +3711,6 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
             bool nonStandardFound = false;
             for (int i=0; i<nonStandardArgs.Height(); i++)
             {
-                hasNonStandardArg = true;
                 if (argx == nonStandardArgs.Index(i).node)
                 {
                     fgArgTabEntry* argEntry = call->fgArgInfo->AddRegArg(argIndex, 
@@ -4002,16 +4005,16 @@ GenTreeCall* Compiler::fgMorphArgs(GenTreeCall* callNode)
     call->gtFlags |= (flagsSummary & GTF_ALL_EFFECT);
 
     // If the register arguments have already been determined
-    // or we have no register arguments then we are done.
-
-    bool needEvalArgsToTemps = true;
-
-    if (lateArgsComputed || (intArgRegNum == 0 && fltArgRegNum == 0 && !hasNonStandardArg && !hasStructArgument))
-    {
-        needEvalArgsToTemps = false;
-    }
-
-    if (needEvalArgsToTemps)
+    // or we have no register arguments then we don't need to 
+    // call SortArgs() and EvalArgsToTemps()
+    //
+    // Note that we do this for UNIX_AMD64 when we have a struct argument
+    //
+    if (!lateArgsComputed && (call->fgArgInfo->HasRegArgs()
+#ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
+                              || hasStructArgument
+#endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
+                              ))
     {
         // This is the first time that we morph this call AND it has register arguments.
         // Follow into the code below and do the 'defer or eval to temp' analysis.