From: Andy Ayers Date: Fri, 17 Feb 2017 22:02:12 +0000 (-0800) Subject: JIT: tolerate GT_COMMA in tail call position X-Git-Tag: submit/tizen/20210909.063632~11030^2~8022^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=e09e70a041c520e70fc0e99560098473bbaad258;p=platform%2Fupstream%2Fdotnet%2Fruntime.git JIT: tolerate GT_COMMA in tail call position Now that we can tail call from inlined call sites, we may see the call embedded in a GT_COMMA, if the call's return value is ignored. This triggered an assert the tail call transformation. Closes dotnet/coreclr#9641. Commit migrated from https://github.com/dotnet/coreclr/commit/f54472efaf841cdcaf01dfe6263b91976045dc1e --- diff --git a/src/coreclr/src/jit/morph.cpp b/src/coreclr/src/jit/morph.cpp index ef752db..b44d6e5 100644 --- a/src/coreclr/src/jit/morph.cpp +++ b/src/coreclr/src/jit/morph.cpp @@ -7875,6 +7875,9 @@ GenTreePtr Compiler::fgMorphCall(GenTreeCall* call) // Either a call stmt or // GT_RETURN(GT_CALL(..)) or GT_RETURN(GT_CAST(GT_CALL(..))) // var = GT_CALL(..) or var = (GT_CAST(GT_CALL(..))) + // GT_COMMA(GT_CALL(..), GT_NOP) or GT_COMMA(GT_CAST(GT_CALL(..)), GT_NOP) + // In the above, + // GT_CASTS may be nested. genTreeOps stmtOper = stmtExpr->gtOper; if (stmtOper == GT_CALL) { @@ -7882,12 +7885,18 @@ GenTreePtr Compiler::fgMorphCall(GenTreeCall* call) } else { - noway_assert(stmtOper == GT_RETURN || stmtOper == GT_ASG); + noway_assert(stmtOper == GT_RETURN || stmtOper == GT_ASG || stmtOper == GT_COMMA); GenTreePtr treeWithCall; if (stmtOper == GT_RETURN) { treeWithCall = stmtExpr->gtGetOp1(); } + else if (stmtOper == GT_COMMA) + { + // Second operation must be nop. + noway_assert(stmtExpr->gtGetOp2()->IsNothingNode()); + treeWithCall = stmtExpr->gtGetOp1(); + } else { treeWithCall = stmtExpr->gtGetOp2(); @@ -7920,10 +7929,11 @@ GenTreePtr Compiler::fgMorphCall(GenTreeCall* call) // 2) tail.call, nop*, pop, nop*, ret // 3) var=tail.call, nop*, ret(var) // 4) var=tail.call, nop*, pop, ret + // 5) comma(tail.call, nop), nop*, ret // // See impIsTailCallILPattern() for details on tail call IL patterns // that are supported. - if ((stmtExpr->gtOper == GT_CALL) || (stmtExpr->gtOper == GT_ASG)) + if (stmtExpr->gtOper != GT_RETURN) { // First delete all GT_NOPs after the call GenTreeStmt* morphStmtToRemove = nullptr;