From 75d368f8bcd985676b069bd80f145aa049c24759 Mon Sep 17 00:00:00 2001 From: Bruce Forstall Date: Thu, 4 Aug 2016 23:52:25 -0700 Subject: [PATCH] Fix dotnet/coreclr#6517 My previous change dotnet/coreclr#6342 to implement tailcall-via-helper for RyuJIT/x86 also changed non-x86 for Delegate Invoke calls, to avoid creating a temp where we already had a local. However, this temp is needed if the local is a field (with an offset). Even if it is not a field, I saw it needed in a JitStressRegs case. So I'm returning it to the previous logic for non-x86, non-tailcall cases. It is still required for tailcall cases to preserve some delicate ordering constraints on the special tailcall argument values. Commit migrated from https://github.com/dotnet/coreclr/commit/021a224809af2104a1c488da1d717d9d80f35cc8 --- src/coreclr/src/jit/lower.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/coreclr/src/jit/lower.cpp b/src/coreclr/src/jit/lower.cpp index e67d260..b5129ca 100644 --- a/src/coreclr/src/jit/lower.cpp +++ b/src/coreclr/src/jit/lower.cpp @@ -2180,14 +2180,23 @@ GenTree* Lowering::LowerDelegateInvoke(GenTreeCall* call) assert(thisArgNode->gtOper == GT_PUTARG_REG); GenTree* originalThisExpr = thisArgNode->gtOp.gtOp1; - // If what we are passing as the thisptr is not already a local, make a new local to place it in - // because we will be creating expressions based on it. + // We're going to use the 'this' expression multiple times, so make a local to copy it. + unsigned lclNum; - if (originalThisExpr->IsLocal()) + +#ifdef _TARGET_X86_ + if (call->IsTailCallViaHelper() && originalThisExpr->IsLocal()) { + // For ordering purposes for the special tailcall arguments on x86, we forced the + // 'this' pointer in this case to a local in Compiler::fgMorphTailCall(). + // We could possibly use this case to remove copies for all architectures and non-tailcall + // calls by creating a new lcl var or lcl field reference, as is done in the + // LowerVirtualVtableCall() code. + assert(originalThisExpr->OperGet() == GT_LCL_VAR); lclNum = originalThisExpr->AsLclVarCommon()->GetLclNum(); } else +#endif // _TARGET_X86_ { unsigned delegateInvokeTmp = comp->lvaGrabTemp(true DEBUGARG("delegate invoke call")); GenTreeStmt* newStmt = comp->fgInsertEmbeddedFormTemp(&thisArgNode->gtOp.gtOp1, delegateInvokeTmp); -- 2.7.4