summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarol Eidt <carol.eidt@microsoft.com>2018-10-09 16:57:03 +0000
committerGitHub <noreply@github.com>2018-10-09 16:57:03 +0000
commitfe00e42185494bb7f27590909d5013b3fc3bbfa7 (patch)
tree59b8ac16849d1d24d43a1ae03eaddac868358c22
parent20cbebbeb151acf901d686dc6beb3a51435edd3d (diff)
parent649d6653ca36f39cfa50cdd92c9efc7f319e24bc (diff)
downloadcoreclr-fe00e42185494bb7f27590909d5013b3fc3bbfa7.tar.gz
coreclr-fe00e42185494bb7f27590909d5013b3fc3bbfa7.tar.bz2
coreclr-fe00e42185494bb7f27590909d5013b3fc3bbfa7.zip
Merge pull request #20078 from CarolEidt/Fix20063
Handle partial multireg COPY
-rw-r--r--src/jit/gentree.h23
-rw-r--r--src/jit/lsra.cpp10
-rw-r--r--src/jit/lsrabuild.cpp10
3 files changed, 28 insertions, 15 deletions
diff --git a/src/jit/gentree.h b/src/jit/gentree.h
index 3fecf008a6..ebeae48cc0 100644
--- a/src/jit/gentree.h
+++ b/src/jit/gentree.h
@@ -5524,22 +5524,25 @@ struct GenTreeCopyOrReload : public GenTreeUnOp
unsigned GetRegCount()
{
- if (gtRegNum == REG_NA)
- {
- return 0;
- }
#if FEATURE_MULTIREG_RET
- for (unsigned i = 0; i < MAX_RET_REG_COUNT - 1; ++i)
+ // We need to return the highest index for which we have a valid register.
+ // Note that the gtOtherRegs array is off by one (the 0th register is gtRegNum).
+ // If there's no valid register in gtOtherRegs, gtRegNum must be valid.
+ // Note that for most nodes, the set of valid registers must be contiguous,
+ // but for COPY or RELOAD there is only a valid register for the register positions
+ // that must be copied or reloaded.
+ //
+ for (unsigned i = MAX_RET_REG_COUNT; i > 1; i--)
{
- if (gtOtherRegs[i] == REG_NA)
+ if (gtOtherRegs[i - 2] != REG_NA)
{
- return i + 1;
+ return i;
}
}
- return MAX_RET_REG_COUNT;
-#else
- return 1;
#endif
+ // We should never have a COPY or RELOAD with no valid registers.
+ assert(gtRegNum != REG_NA);
+ return 1;
}
GenTreeCopyOrReload(genTreeOps oper, var_types type, GenTree* op1) : GenTreeUnOp(oper, type, op1)
diff --git a/src/jit/lsra.cpp b/src/jit/lsra.cpp
index 02bfc2a4e2..8a613b660e 100644
--- a/src/jit/lsra.cpp
+++ b/src/jit/lsra.cpp
@@ -9237,6 +9237,16 @@ void LinearScan::dumpLsraAllocationEvent(LsraDumpEvent event,
case LSRA_EVENT_DEFUSE_CASE6:
printf(indentFormat, " Case #6 need a copy");
dumpRegRecords();
+ if (interval == nullptr)
+ {
+ printf(indentFormat, " NULL interval");
+ dumpRegRecords();
+ }
+ else if (interval->firstRefPosition->multiRegIdx != 0)
+ {
+ printf(indentFormat, " (multiReg)");
+ dumpRegRecords();
+ }
break;
case LSRA_EVENT_SPILL:
diff --git a/src/jit/lsrabuild.cpp b/src/jit/lsrabuild.cpp
index 69785a7f68..6dd2c14d89 100644
--- a/src/jit/lsrabuild.cpp
+++ b/src/jit/lsrabuild.cpp
@@ -315,7 +315,7 @@ void LinearScan::resolveConflictingDefAndUse(Interval* interval, RefPosition* de
if (!useRegConflict)
{
// This is case #2. Use the useRegAssignment
- INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE2));
+ INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE2, interval));
defRefPosition->registerAssignment = useRegAssignment;
return;
}
@@ -328,21 +328,21 @@ void LinearScan::resolveConflictingDefAndUse(Interval* interval, RefPosition* de
if (defRegRecord != nullptr && !useRegConflict)
{
// This is case #3.
- INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE3));
+ INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE3, interval));
defRefPosition->registerAssignment = useRegAssignment;
return;
}
if (useRegRecord != nullptr && !defRegConflict && canChangeUseAssignment)
{
// This is case #4.
- INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE4));
+ INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE4, interval));
useRefPosition->registerAssignment = defRegAssignment;
return;
}
if (defRegRecord != nullptr && useRegRecord != nullptr)
{
// This is case #5.
- INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE5));
+ INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE5, interval));
RegisterType regType = interval->registerType;
assert((getRegisterType(interval, defRefPosition) == regType) &&
(getRegisterType(interval, useRefPosition) == regType));
@@ -350,7 +350,7 @@ void LinearScan::resolveConflictingDefAndUse(Interval* interval, RefPosition* de
defRefPosition->registerAssignment = candidates;
return;
}
- INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE6));
+ INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE6, interval));
return;
}