@@ -9613,6 +9613,29 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
96139613 }
96149614 }
96159615
9616+ #ifdef TARGET_ARM
9617+ auto addOtherHalfRegToReady = [&](regNumber otherHalfReg) {
9618+ // For a double interval, if the first half if freed up, check if the other
9619+ // half can also be freed (if it is a target for resolution).
9620+
9621+ regNumber otherHalfSrcReg = (regNumber)source[otherHalfReg];
9622+ regNumber otherHalfSrcLoc = (regNumber)location[otherHalfReg];
9623+
9624+ // Necessary conditions:
9625+ // - There is a source register for this reg (otherHalfSrcReg != REG_NA)
9626+ // - It is currently free (otherHalfSrcLoc == REG_NA)
9627+ // - The source interval isn't yet completed (sourceIntervals[otherHalfSrcReg] != nullptr)
9628+ // - It's in the TODO set (targetRegsToDo.IsRegNumInMask(otherHalfReg))
9629+ // - It's not resolved from stack (!targetRegsFromStack.IsRegNumInMask(otherHalfReg))
9630+ if ((otherHalfSrcReg != REG_NA) && (otherHalfSrcLoc == REG_NA) &&
9631+ (sourceIntervals[otherHalfSrcReg] != nullptr) && targetRegsToDo.IsRegNumInMask(otherHalfReg) &&
9632+ !targetRegsFromStack.IsRegNumInMask(otherHalfReg))
9633+ {
9634+ targetRegsReady.AddRegNumInMask(otherHalfReg);
9635+ }
9636+ };
9637+ #endif // TARGET_ARM
9638+
96169639 // Perform reg to reg moves
96179640 while (targetRegsToDo.IsNonEmpty())
96189641 {
@@ -9654,48 +9677,18 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
96549677 }
96559678
96569679 // Since we want to check if we can free upperHalfReg, only do it
9657- // if lowerHalfReg is ready.
9680+ // if lowerHalfReg is ready and it is one of the target candidate .
96589681 if (targetRegsReady.IsRegNumInMask(fromReg))
96599682 {
9660- regNumber upperHalfSrcReg = (regNumber)source[upperHalfReg];
9661- regNumber upperHalfSrcLoc = (regNumber)location[upperHalfReg];
9662- // Necessary conditions:
9663- // - There is a source register for this reg (upperHalfSrcReg != REG_NA)
9664- // - It is currently free (upperHalfSrcLoc == REG_NA)
9665- // - The source interval isn't yet completed (sourceIntervals[upperHalfSrcReg] != nullptr)
9666- // - It's not resolved from stack (!targetRegsFromStack.IsRegNumInMask(upperHalfReg))
9667- if ((upperHalfSrcReg != REG_NA) && (upperHalfSrcLoc == REG_NA) &&
9668- (sourceIntervals[upperHalfSrcReg] != nullptr) &&
9669- !targetRegsFromStack.IsRegNumInMask(upperHalfReg))
9670- {
9671- targetRegsReady.AddRegNumInMask(upperHalfReg);
9672- }
9683+ addOtherHalfRegToReady(upperHalfReg);
96739684 }
96749685 }
96759686 }
96769687 else if (genIsValidFloatReg(fromReg) && !genIsValidDoubleReg(fromReg))
96779688 {
96789689 // We may have freed up the other half of a double where the lower half
96799690 // was already free.
9680- regNumber lowerHalfReg = REG_PREV(fromReg);
9681- regNumber lowerHalfSrcReg = (regNumber)source[lowerHalfReg];
9682- regNumber lowerHalfSrcLoc = (regNumber)location[lowerHalfReg];
9683- // Necessary conditions:
9684- // - There is a source register for this reg (lowerHalfSrcReg != REG_NA)
9685- // - It is currently free (lowerHalfSrcLoc == REG_NA)
9686- // - The source interval isn't yet completed (sourceIntervals[lowerHalfSrcReg] != nullptr)
9687- // - It's not in the ready set (!targetRegsReady.IsRegNumInMask(lowerHalfReg))
9688- // - It's not resolved from stack (!targetRegsFromStack.IsRegNumInMask(lowerHalfReg))
9689- if ((lowerHalfSrcReg != REG_NA) && (lowerHalfSrcLoc == REG_NA) &&
9690- (sourceIntervals[lowerHalfSrcReg] != nullptr) &&
9691- !targetRegsReady.IsRegNumInMask(lowerHalfReg) &&
9692- !targetRegsFromStack.IsRegNumInMask(lowerHalfReg))
9693- {
9694- // This must be a double interval, otherwise it would be in targetRegsReady, or already
9695- // completed.
9696- assert(sourceIntervals[lowerHalfSrcReg]->registerType == TYP_DOUBLE);
9697- targetRegsReady.AddRegNumInMask(lowerHalfReg);
9698- }
9691+ addOtherHalfRegToReady(REG_PREV(fromReg));
96999692#endif // TARGET_ARM
97009693 }
97019694 }
@@ -9870,6 +9863,14 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
98709863 targetReg DEBUG_ARG(fromBlock) DEBUG_ARG(toBlock)
98719864 DEBUG_ARG(resolveTypeName[resolveType]));
98729865 location[targetReg] = (regNumberSmall)tempReg;
9866+
9867+ if (sourceIntervals[targetReg]->registerType == TYP_DOUBLE)
9868+ {
9869+ // Free up upperHalf reg of this targetReg, if it is one of the target candidate.
9870+
9871+ assert(genIsValidDoubleReg(targetReg));
9872+ addOtherHalfRegToReady(REG_NEXT(targetReg));
9873+ }
98739874 }
98749875#else
98759876 assert(sourceIntervals[targetReg] != nullptr);
0 commit comments