From d00887d6f48f7f39f874dd14545f7457c9f55987 Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 13 Jan 2021 11:09:03 -0800 Subject: [PATCH 1/3] free the second half of double register --- src/coreclr/jit/lsra.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 5add9f563e527b..66308b3aa0c333 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -4923,7 +4923,8 @@ void LinearScan::processBlockStartLocations(BasicBlock* currentBlock) { #ifdef TARGET_ARM // If this is a TYP_DOUBLE interval, and the assigned interval is either null or is TYP_FLOAT, - // we also need to unassign the other half of the register. + // we also need to unassign the other half of the register so it is free to get assigned to + // this interval. // Note that if the assigned interval is TYP_DOUBLE, it will be unassigned below. if ((interval->registerType == TYP_DOUBLE) && ((targetRegRecord->assignedInterval == nullptr) || @@ -4933,6 +4934,16 @@ void LinearScan::processBlockStartLocations(BasicBlock* currentBlock) unassignIntervalBlockStart(getSecondHalfRegRec(targetRegRecord), allocationPassComplete ? nullptr : inVarToRegMap); } + + // If this is a TYP_FLOAT interval, and the assigned interval was TYP_DOUBLE, we also + // need to update the liveRegs to specify that the other half is not live anymore. + if ((interval->registerType == TYP_FLOAT) && + ((targetRegRecord->assignedInterval != nullptr) && + (targetRegRecord->assignedInterval->registerType == TYP_DOUBLE))) + { + liveRegs &= ~getRegMask(getSecondHalfRegRec(targetRegRecord)->regNum, TYP_DOUBLE); + } + #endif // TARGET_ARM unassignIntervalBlockStart(targetRegRecord, allocationPassComplete ? nullptr : inVarToRegMap); assignPhysReg(targetRegRecord, interval); From 9d6b279a1d3e329bb7d5a7bfc2cb5ad7b970357d Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Wed, 13 Jan 2021 23:46:10 -0800 Subject: [PATCH 2/3] Take appropriate regmask --- src/coreclr/jit/lsra.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 66308b3aa0c333..474806d44bbdc1 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -4937,11 +4937,15 @@ void LinearScan::processBlockStartLocations(BasicBlock* currentBlock) // If this is a TYP_FLOAT interval, and the assigned interval was TYP_DOUBLE, we also // need to update the liveRegs to specify that the other half is not live anymore. + // As mentioned above, for TYP_DOUBLE, the other half will be unassigned further below. if ((interval->registerType == TYP_FLOAT) && ((targetRegRecord->assignedInterval != nullptr) && (targetRegRecord->assignedInterval->registerType == TYP_DOUBLE))) { - liveRegs &= ~getRegMask(getSecondHalfRegRec(targetRegRecord)->regNum, TYP_DOUBLE); + RegRecord* anotherHalfRegRec = findAnotherHalfRegRec(targetRegRecord); + + // Use TYP_FLOAT to get the regmask of just the half reg. + liveRegs &= ~getRegMask(anotherHalfRegRec->regNum, TYP_FLOAT); } #endif // TARGET_ARM From becad8eb09a6dd8f038a570e5ac1ce67a7aec8dc Mon Sep 17 00:00:00 2001 From: Kunal Pathak Date: Thu, 14 Jan 2021 13:32:23 -0800 Subject: [PATCH 3/3] revert part of comment --- src/coreclr/jit/lsra.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 474806d44bbdc1..d7e8fcf08ef982 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -4923,8 +4923,7 @@ void LinearScan::processBlockStartLocations(BasicBlock* currentBlock) { #ifdef TARGET_ARM // If this is a TYP_DOUBLE interval, and the assigned interval is either null or is TYP_FLOAT, - // we also need to unassign the other half of the register so it is free to get assigned to - // this interval. + // we also need to unassign the other half of the register. // Note that if the assigned interval is TYP_DOUBLE, it will be unassigned below. if ((interval->registerType == TYP_DOUBLE) && ((targetRegRecord->assignedInterval == nullptr) ||