From 90172bedd4260e5038450e4e7ee4ad46f0e16afc Mon Sep 17 00:00:00 2001 From: Mike Danes Date: Sun, 13 Nov 2016 11:56:46 +0200 Subject: [PATCH] Fix GT_MULHI register requirements We only care about the upper 32 bits of the 64 bit result and those are in EDX. It doesn't make sense to set the destination candidate to EAX, most of the time this will result in a useless `mov eax, edx` being generated. Also, genCodeForMulHi needs to check if the implicit operand is in EAX rather than targetReg. Commit migrated from https://github.com/dotnet/coreclr/commit/0822b57867aaae098239022e7ebaef745588b8a4 --- src/coreclr/src/jit/codegenxarch.cpp | 6 +++--- src/coreclr/src/jit/lowerxarch.cpp | 13 +++++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/coreclr/src/jit/codegenxarch.cpp b/src/coreclr/src/jit/codegenxarch.cpp index 5e4153c..53f0cc8 100644 --- a/src/coreclr/src/jit/codegenxarch.cpp +++ b/src/coreclr/src/jit/codegenxarch.cpp @@ -515,7 +515,7 @@ void CodeGen::genCodeForMulHi(GenTreeOp* treeNode) GenTree* rmOp = op2; // Set rmOp to the contained memory operand (if any) - if (op1->isContained() || (!op2->isContained() && (op2->gtRegNum == targetReg))) + if (op1->isContained() || (!op2->isContained() && (op2->gtRegNum == REG_RAX))) { regOp = op2; rmOp = op1; @@ -523,9 +523,9 @@ void CodeGen::genCodeForMulHi(GenTreeOp* treeNode) assert(!regOp->isContained()); // Setup targetReg when neither of the source operands was a matching register - if (regOp->gtRegNum != targetReg) + if (regOp->gtRegNum != REG_RAX) { - inst_RV_RV(ins_Copy(targetType), targetReg, regOp->gtRegNum, targetType); + inst_RV_RV(ins_Copy(targetType), REG_RAX, regOp->gtRegNum, targetType); } instruction ins; diff --git a/src/coreclr/src/jit/lowerxarch.cpp b/src/coreclr/src/jit/lowerxarch.cpp index da51f3a..299d213 100644 --- a/src/coreclr/src/jit/lowerxarch.cpp +++ b/src/coreclr/src/jit/lowerxarch.cpp @@ -4365,16 +4365,21 @@ void Lowering::SetMulOpCounts(GenTreePtr tree) info->setDstCandidates(m_lsra, RBM_RAX); hasImpliedFirstOperand = true; } - else if (tree->gtOper == GT_MULHI + else if (tree->OperGet() == GT_MULHI) + { + // Have to use the encoding:RDX:RAX = RAX * rm. Since we only care about the + // upper 32 bits of the result set the destination candidate to REG_RDX. + info->setDstCandidates(m_lsra, RBM_RDX); + hasImpliedFirstOperand = true; + } #if defined(_TARGET_X86_) - || tree->OperGet() == GT_MUL_LONG -#endif - ) + else if (tree->OperGet() == GT_MUL_LONG) { // have to use the encoding:RDX:RAX = RAX * rm info->setDstCandidates(m_lsra, RBM_RAX); hasImpliedFirstOperand = true; } +#endif else if (IsContainableImmed(tree, op2) || IsContainableImmed(tree, op1)) { if (IsContainableImmed(tree, op2)) -- 2.7.4