summaryrefslogtreecommitdiff
path: root/src/jit/lsra.cpp
diff options
context:
space:
mode:
authorCarol Eidt <carol.eidt@microsoft.com>2018-03-22 09:54:00 -0700
committerCarol Eidt <carol.eidt@microsoft.com>2018-03-22 09:54:00 -0700
commit240ea0c7feecd8325af704be18022eb9c3b6b2f9 (patch)
tree98e7a973447a4dec6f3f9d18e28af44185c0ac6a /src/jit/lsra.cpp
parentd6b2ead7f821e06b8e7bdc4a82812d1cfbc732ac (diff)
downloadcoreclr-240ea0c7feecd8325af704be18022eb9c3b6b2f9.tar.gz
coreclr-240ea0c7feecd8325af704be18022eb9c3b6b2f9.tar.bz2
coreclr-240ea0c7feecd8325af704be18022eb9c3b6b2f9.zip
ARM: Fix reg resolution for doubles
1) When an odd float register becomes free, we may need to add the corresponding (even) double register to `targetRegsReady` (this was the bug) 2) When an even float register becomes free, we can't add it to `targetRegsReady` unless it's other half is also free.
Diffstat (limited to 'src/jit/lsra.cpp')
-rw-r--r--src/jit/lsra.cpp31
1 files changed, 28 insertions, 3 deletions
diff --git a/src/jit/lsra.cpp b/src/jit/lsra.cpp
index 6727599e48..8bf17effe8 100644
--- a/src/jit/lsra.cpp
+++ b/src/jit/lsra.cpp
@@ -8260,10 +8260,35 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
location[sourceReg] = REG_NA;
// Do we have a free targetReg?
- if (fromReg == sourceReg && source[fromReg] != REG_NA)
+ if (fromReg == sourceReg)
{
- regMaskTP fromRegMask = genRegMask(fromReg);
- targetRegsReady |= fromRegMask;
+ if (source[fromReg] != REG_NA)
+ {
+ regMaskTP fromRegMask = genRegMask(fromReg);
+ targetRegsReady |= fromRegMask;
+#ifdef _TARGET_ARM_
+ if (genIsValidDoubleReg(fromReg))
+ {
+ // Ensure that the other half is free.
+ Interval* otherInterval = sourceIntervals[source[fromReg]];
+ regNumber upperHalfReg = REG_NEXT(fromReg);
+ if ((otherInterval->registerType == TYP_DOUBLE) && (location[upperHalfReg] != REG_NA))
+ {
+ targetRegsReady &= ~fromRegMask;
+ }
+ }
+ }
+ else if (genIsValidFloatReg(fromReg) && !genIsValidDoubleReg(fromReg))
+ {
+ // We may have freed up the other half of a double where the lower half
+ // was already free.
+ regNumber lowerHalfReg = REG_PREV(fromReg);
+ if (location[lowerHalfReg] == REG_NA)
+ {
+ targetRegsReady |= genRegMask(lowerHalfReg);
+ }
+#endif // _TARGET_ARM_
+ }
}
}
if (targetRegsToDo != RBM_NONE)