Skip to content

Commit

Permalink
Fix multi-reg copy (#37062)
Browse files Browse the repository at this point in the history
Also, fix dump for multi-reg copy.

Fix #37059
  • Loading branch information
CarolEidt authored May 27, 2020
1 parent 0c043d5 commit ef72b95
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 24 deletions.
14 changes: 8 additions & 6 deletions src/coreclr/src/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11750,8 +11750,8 @@ void CodeGen::genRegCopy(GenTree* treeNode)
// There should never be any circular dependencies, and we will check that here.

GenTreeCopyOrReload* copyNode = treeNode->AsCopyOrReload();
unsigned regCount = copyNode->GetRegCount();
// GenTreeCopyOrReload only reports the number of registers that are valid.
// GenTreeCopyOrReload only reports the highest index that has a valid register.
unsigned regCount = copyNode->GetRegCount();
assert(regCount <= MAX_MULTIREG_COUNT);

// First set the source registers as busy if they haven't been spilled.
Expand All @@ -11767,13 +11767,15 @@ void CodeGen::genRegCopy(GenTree* treeNode)
// First do any copies - we'll do the reloads after all the copies are complete.
for (unsigned i = 0; i < regCount; ++i)
{
regNumber sourceReg = op1->GetRegByIndex(i);
regNumber targetReg = copyNode->GetRegNumByIdx(i);
regMaskTP targetRegMask = genRegMask(targetReg);
// GenTreeCopyOrReload only reports the number of registers that are valid.
regNumber sourceReg = op1->GetRegByIndex(i);
regNumber targetReg = copyNode->GetRegNumByIdx(i);
// GenTreeCopyOrReload only reports the highest index that has a valid register.
// However there may be lower indices that have no valid register (i.e. the register
// on the source is still valid at the consumer).
if (targetReg != REG_NA)
{
// We shouldn't specify a no-op move.
regMaskTP targetRegMask = genRegMask(targetReg);
assert(sourceReg != targetReg);
assert((busyRegs & targetRegMask) == 0);
// Clear sourceReg from the busyRegs, and add targetReg.
Expand Down
46 changes: 28 additions & 18 deletions src/coreclr/src/jit/gentree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10205,9 +10205,10 @@ void Compiler::gtDispRegVal(GenTree* tree)
break;
}

#if FEATURE_MULTIREG_RET
if (tree->IsMultiRegCall())
{
// 0th reg is GettRegNum(), which is already printed above.
// 0th reg is GetRegNum(), which is already printed above.
// Print the remaining regs of a multi-reg call node.
const GenTreeCall* call = tree->AsCall();
const unsigned regCount = call->GetReturnTypeDesc()->TryGetReturnRegCount();
Expand All @@ -10216,28 +10217,37 @@ void Compiler::gtDispRegVal(GenTree* tree)
printf(",%s", compRegVarName(call->GetRegNumByIdx(i)));
}
}
else if (tree->IsCopyOrReloadOfMultiRegCall())
else if (tree->IsCopyOrReload())
{
GenTree* op1 = tree->gtGetOp1();
const GenTreeCopyOrReload* copyOrReload = tree->AsCopyOrReload();
const GenTreeCall* call = tree->gtGetOp1()->AsCall();
const unsigned regCount = call->GetReturnTypeDesc()->TryGetReturnRegCount();
for (unsigned i = 1; i < regCount; ++i)
unsigned regCount = 0;
if (op1->OperIs(GT_CALL))
{
printf(",%s", compRegVarName(copyOrReload->GetRegNumByIdx(i)));
}
}

#if FEATURE_MULTIREG_RET
if (tree->IsCopyOrReload())
{
for (int i = 1; i < MAX_RET_REG_COUNT; i++)
{
regNumber reg = (regNumber)tree->AsCopyOrReload()->GetRegNumByIdx(i);
if (reg == REG_NA)
if (op1->IsMultiRegCall())
{
break;
regCount = op1->AsCall()->GetReturnTypeDesc()->TryGetReturnRegCount();
// If it hasn't yet been initialized, we'd still like to see the registers printed.
if (regCount == 0)
{
regCount = MAX_RET_REG_COUNT;
}
}
printf(",%s", compRegVarName(reg));
}
else if (op1->IsMultiRegLclVar())
{
regCount = op1->AsLclVar()->GetFieldCount(this);
}
else if (op1->IsMultiRegNode())
{
regCount = op1->GetMultiRegCount();
}
// We will only have valid regs for positions that require copy or reload.
// But we'd like to keep track of where they are so we print all positions.
for (unsigned i = 1; i < regCount; i++)
{
regNumber reg = tree->AsCopyOrReload()->GetRegNumByIdx(i);
printf(",%s", (reg == REG_NA) ? ",NA" : compRegVarName(reg));
}
}
#endif
Expand Down

0 comments on commit ef72b95

Please sign in to comment.