Skip to content

Commit ef72b95

Browse files
authored
Fix multi-reg copy (#37062)
Also, fix dump for multi-reg copy. Fix #37059
1 parent 0c043d5 commit ef72b95

File tree

2 files changed

+36
-24
lines changed

2 files changed

+36
-24
lines changed

src/coreclr/src/jit/codegencommon.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -11750,8 +11750,8 @@ void CodeGen::genRegCopy(GenTree* treeNode)
1175011750
// There should never be any circular dependencies, and we will check that here.
1175111751

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

1175711757
// First set the source registers as busy if they haven't been spilled.
@@ -11767,13 +11767,15 @@ void CodeGen::genRegCopy(GenTree* treeNode)
1176711767
// First do any copies - we'll do the reloads after all the copies are complete.
1176811768
for (unsigned i = 0; i < regCount; ++i)
1176911769
{
11770-
regNumber sourceReg = op1->GetRegByIndex(i);
11771-
regNumber targetReg = copyNode->GetRegNumByIdx(i);
11772-
regMaskTP targetRegMask = genRegMask(targetReg);
11773-
// GenTreeCopyOrReload only reports the number of registers that are valid.
11770+
regNumber sourceReg = op1->GetRegByIndex(i);
11771+
regNumber targetReg = copyNode->GetRegNumByIdx(i);
11772+
// GenTreeCopyOrReload only reports the highest index that has a valid register.
11773+
// However there may be lower indices that have no valid register (i.e. the register
11774+
// on the source is still valid at the consumer).
1177411775
if (targetReg != REG_NA)
1177511776
{
1177611777
// We shouldn't specify a no-op move.
11778+
regMaskTP targetRegMask = genRegMask(targetReg);
1177711779
assert(sourceReg != targetReg);
1177811780
assert((busyRegs & targetRegMask) == 0);
1177911781
// Clear sourceReg from the busyRegs, and add targetReg.

src/coreclr/src/jit/gentree.cpp

+28-18
Original file line numberDiff line numberDiff line change
@@ -10205,9 +10205,10 @@ void Compiler::gtDispRegVal(GenTree* tree)
1020510205
break;
1020610206
}
1020710207

10208+
#if FEATURE_MULTIREG_RET
1020810209
if (tree->IsMultiRegCall())
1020910210
{
10210-
// 0th reg is GettRegNum(), which is already printed above.
10211+
// 0th reg is GetRegNum(), which is already printed above.
1021110212
// Print the remaining regs of a multi-reg call node.
1021210213
const GenTreeCall* call = tree->AsCall();
1021310214
const unsigned regCount = call->GetReturnTypeDesc()->TryGetReturnRegCount();
@@ -10216,28 +10217,37 @@ void Compiler::gtDispRegVal(GenTree* tree)
1021610217
printf(",%s", compRegVarName(call->GetRegNumByIdx(i)));
1021710218
}
1021810219
}
10219-
else if (tree->IsCopyOrReloadOfMultiRegCall())
10220+
else if (tree->IsCopyOrReload())
1022010221
{
10222+
GenTree* op1 = tree->gtGetOp1();
1022110223
const GenTreeCopyOrReload* copyOrReload = tree->AsCopyOrReload();
10222-
const GenTreeCall* call = tree->gtGetOp1()->AsCall();
10223-
const unsigned regCount = call->GetReturnTypeDesc()->TryGetReturnRegCount();
10224-
for (unsigned i = 1; i < regCount; ++i)
10224+
unsigned regCount = 0;
10225+
if (op1->OperIs(GT_CALL))
1022510226
{
10226-
printf(",%s", compRegVarName(copyOrReload->GetRegNumByIdx(i)));
10227-
}
10228-
}
10229-
10230-
#if FEATURE_MULTIREG_RET
10231-
if (tree->IsCopyOrReload())
10232-
{
10233-
for (int i = 1; i < MAX_RET_REG_COUNT; i++)
10234-
{
10235-
regNumber reg = (regNumber)tree->AsCopyOrReload()->GetRegNumByIdx(i);
10236-
if (reg == REG_NA)
10227+
if (op1->IsMultiRegCall())
1023710228
{
10238-
break;
10229+
regCount = op1->AsCall()->GetReturnTypeDesc()->TryGetReturnRegCount();
10230+
// If it hasn't yet been initialized, we'd still like to see the registers printed.
10231+
if (regCount == 0)
10232+
{
10233+
regCount = MAX_RET_REG_COUNT;
10234+
}
1023910235
}
10240-
printf(",%s", compRegVarName(reg));
10236+
}
10237+
else if (op1->IsMultiRegLclVar())
10238+
{
10239+
regCount = op1->AsLclVar()->GetFieldCount(this);
10240+
}
10241+
else if (op1->IsMultiRegNode())
10242+
{
10243+
regCount = op1->GetMultiRegCount();
10244+
}
10245+
// We will only have valid regs for positions that require copy or reload.
10246+
// But we'd like to keep track of where they are so we print all positions.
10247+
for (unsigned i = 1; i < regCount; i++)
10248+
{
10249+
regNumber reg = tree->AsCopyOrReload()->GetRegNumByIdx(i);
10250+
printf(",%s", (reg == REG_NA) ? ",NA" : compRegVarName(reg));
1024110251
}
1024210252
}
1024310253
#endif

0 commit comments

Comments
 (0)