From 2b110935f467b4abcb81785009486e0789180d10 Mon Sep 17 00:00:00 2001 From: Qiao Pengcheng Date: Wed, 17 May 2023 19:46:10 +0800 Subject: [PATCH] fix the regs conflicts within the `addResolution` for LoongArch64 and RISC-V. (#86294) * Fix the regs conflicts within the `addResolution` for LoongArch64/RISC-V. * amend the code for CR. * add terminatorNodeLclVarDsc2 for the second op2. --- src/coreclr/jit/lsra.cpp | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index cc9a253de7cd2..277ad0dd86684 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -8118,7 +8118,8 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block) } } - LclVarDsc* terminatorNodeLclVarDsc = nullptr; + LclVarDsc* terminatorNodeLclVarDsc = nullptr; + LclVarDsc* terminatorNodeLclVarDsc2 = nullptr; // Next, if this blocks ends with a switch table, or for Arm64, ends with JCMP/JTEST instruction, // make sure to not copy into the registers that are consumed at the end of this block. // @@ -8178,18 +8179,28 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block) GenTree* srcOp = op->gtGetOp1(); consumedRegs |= genRegMask(srcOp->GetRegNum()); } - - if (op->IsLocal()) + else if (op->IsLocal()) { GenTreeLclVarCommon* lcl = op->AsLclVarCommon(); terminatorNodeLclVarDsc = &compiler->lvaTable[lcl->GetLclNum()]; } -#if !defined(TARGET_LOONGARCH64) && !defined(TARGET_RISCV64) - // TODO-LOONGARCH64: Take into account that on LA64, the second - // operand of a JCMP can be in a register too. - assert(!lastNode->OperIs(GT_JCMP, GT_JTEST) || lastNode->gtGetOp2()->isContained()); -#endif + if (lastNode->OperIs(GT_JCMP, GT_JTEST) && !lastNode->gtGetOp2()->isContained()) + { + op = lastNode->gtGetOp2(); + consumedRegs |= genRegMask(op->GetRegNum()); + + if (op->OperIs(GT_COPY)) + { + GenTree* srcOp = op->gtGetOp1(); + consumedRegs |= genRegMask(srcOp->GetRegNum()); + } + else if (op->IsLocal()) + { + GenTreeLclVarCommon* lcl = op->AsLclVarCommon(); + terminatorNodeLclVarDsc2 = &compiler->lvaTable[lcl->GetLclNum()]; + } + } } } @@ -8273,6 +8284,11 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block) { sameToReg = REG_NA; } + else if ((terminatorNodeLclVarDsc2 != nullptr) && + (terminatorNodeLclVarDsc2->lvVarIndex == outResolutionSetVarIndex)) + { + sameToReg = REG_NA; + } #endif // defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) // If the var is live only at those blocks connected by a split edge and not live-in at some of the