diff options
author | Carol Eidt <carol.eidt@microsoft.com> | 2017-10-26 13:53:44 -0700 |
---|---|---|
committer | Carol Eidt <carol.eidt@microsoft.com> | 2017-10-26 13:53:44 -0700 |
commit | dfbebfdbeb34e159e093d7f2bd69f30ee5d53a9f (patch) | |
tree | ca523645bd2cd436a115c27e4eb4de90ce39cc78 | |
parent | 7baaffcedf99de24373d15122f2a4148e18ba6e4 (diff) | |
download | coreclr-dfbebfdbeb34e159e093d7f2bd69f30ee5d53a9f.tar.gz coreclr-dfbebfdbeb34e159e093d7f2bd69f30ee5d53a9f.tar.bz2 coreclr-dfbebfdbeb34e159e093d7f2bd69f30ee5d53a9f.zip |
Fix FixedReg assert
With JitStressRegs (various values) it is possible to have RefPositions that have a single candidate, even though they are not really a fixed reference to the given register.
Fix #14624
-rw-r--r-- | src/jit/lsra.cpp | 11 | ||||
-rw-r--r-- | src/jit/lsra.h | 9 |
2 files changed, 16 insertions, 4 deletions
diff --git a/src/jit/lsra.cpp b/src/jit/lsra.cpp index 3c5366ada4..b4c4bff394 100644 --- a/src/jit/lsra.cpp +++ b/src/jit/lsra.cpp @@ -6168,16 +6168,19 @@ bool LinearScan::isSpillCandidate(Interval* current, if (refPosition->isFixedRefOfRegMask(candidateBit)) { - // Either there is a fixed reference due to this node, or one associated with a - // fixed use fed by a def at this node. - // In either case, we must use this register as it's the only candidate + // Either: + // - there is a fixed reference due to this node, OR + // - or there is a fixed use fed by a def at this node, OR + // - or we have restricted the set of registers for stress. + // In any case, we must use this register as it's the only candidate // TODO-CQ: At the time we allocate a register to a fixed-reg def, if it's not going // to remain live until the use, we should set the candidates to allRegs(regType) // to avoid a spill - codegen can then insert the copy. // If this is marked as allocateIfProfitable, the caller will compare the weights // of this RefPosition and the RefPosition to which it is currently assigned. assert(refPosition->isFixedRegRef || - (refPosition->nextRefPosition != nullptr && refPosition->nextRefPosition->isFixedRegRef)); + (refPosition->nextRefPosition != nullptr && refPosition->nextRefPosition->isFixedRegRef) || + candidatesAreStressLimited()); return true; } diff --git a/src/jit/lsra.h b/src/jit/lsra.h index 55ebe5e8d5..001c59ef9c 100644 --- a/src/jit/lsra.h +++ b/src/jit/lsra.h @@ -630,6 +630,11 @@ private: return getLsraRegOptionalControl() == LSRA_REG_OPTIONAL_NO_ALLOC; } + bool candidatesAreStressLimited() + { + return ((lsraStressMask & (LSRA_LIMIT_MASK | LSRA_SELECT_MASK)) != 0); + } + // Dump support void lsraDumpIntervals(const char* msg); void dumpRefPositions(const char* msg); @@ -666,6 +671,10 @@ private: { return false; } + bool candidatesAreStressLimited() + { + return false; + } #endif // !DEBUG public: |