From 253dafe3004850810e60edad06e570f605f0ef58 Mon Sep 17 00:00:00 2001 From: Brian Sullivan Date: Thu, 16 Jun 2016 10:06:55 -0700 Subject: [PATCH] Fix for issue 5795 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 | 4 ++++ src/coreclr/src/jit/morph.cpp | 27 +++++++++++++++------------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/coreclr/src/jit/compiler.h b/src/coreclr/src/jit/compiler.h index c93f565..e38a31f 100644 --- a/src/coreclr/src/jit/compiler.h +++ b/src/coreclr/src/jit/compiler.h @@ -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; } }; diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index 39e0239..98b3a43 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -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; ifgArgInfo->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. -- 2.7.4