diff options
author | Carol Eidt <carol.eidt@microsoft.com> | 2018-10-09 16:57:03 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-09 16:57:03 +0000 |
commit | fe00e42185494bb7f27590909d5013b3fc3bbfa7 (patch) | |
tree | 59b8ac16849d1d24d43a1ae03eaddac868358c22 | |
parent | 20cbebbeb151acf901d686dc6beb3a51435edd3d (diff) | |
parent | 649d6653ca36f39cfa50cdd92c9efc7f319e24bc (diff) | |
download | coreclr-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.h | 23 | ||||
-rw-r--r-- | src/jit/lsra.cpp | 10 | ||||
-rw-r--r-- | src/jit/lsrabuild.cpp | 10 |
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; } |