From b40321e38dd97b783657e26942eb3fbd6029daef Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Mon, 26 Apr 2021 17:34:45 -0700 Subject: [PATCH] JIT: generalize checking for valid IR after a tail call Allow NOPs and assignments with non-overflowing casts, in addition to the assignments we already allowed. Closes #51898. --- src/coreclr/jit/morph.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index e0b39011eaeb82..4260c75f43bb23 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -7659,6 +7659,9 @@ GenTree* Compiler::fgMorphPotentialTailCall(GenTreeCall* call) // Check if we have a sequence of GT_ASG blocks where the same variable is assigned // to temp locals over and over. + // + // Also allow casts on the RHSs of the assignments, and blocks with GT_NOPs. + // if (nextNextBlock->bbJumpKind != BBJ_RETURN) { // Make sure the block has a single statement @@ -7673,9 +7676,20 @@ GenTree* Compiler::fgMorphPotentialTailCall(GenTreeCall* call) { assert(nextNextBlock->firstStmt() == nextNextBlock->lastStmt()); asgNode = nextNextBlock->firstStmt()->GetRootNode(); - assert(asgNode->OperIs(GT_ASG)); - assert(lcl == asgNode->gtGetOp2()->AsLclVarCommon()->GetLclNum()); - lcl = asgNode->gtGetOp1()->AsLclVarCommon()->GetLclNum(); + if (!asgNode->OperIs(GT_NOP)) + { + assert(asgNode->OperIs(GT_ASG)); + + GenTree* rhs = asgNode->gtGetOp2(); + while (rhs->OperIs(GT_CAST)) + { + assert(!rhs->gtOverflow()); + rhs = rhs->gtGetOp1(); + } + + assert(lcl == rhs->AsLclVarCommon()->GetLclNum()); + lcl = rhs->AsLclVarCommon()->GetLclNum(); + } nextNextBlock = nextNextBlock->GetUniqueSucc(); } }