From 58e9f4a3db590b6a8a8eea2c7fd938ceb07eb5a4 Mon Sep 17 00:00:00 2001 From: Pat Gavlin Date: Fri, 28 Jul 2017 11:42:16 -0700 Subject: [PATCH] Only lock unlocked registers in `rsUnspillRegPair`. `rsUnspillRegPair` needs to lock the hi/lo part of the reg pair when unspilling the lo/hi part in order to ensure that the two parts of the pair do not end up in the same register. However, the register to be locked may already be locked if it is a multi-use register. In this case `rsUnspillRegPair` does not need to re-lock the register. Fixes #12910. --- src/jit/regset.cpp | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/src/jit/regset.cpp b/src/jit/regset.cpp index 7204663..20551fa 100644 --- a/src/jit/regset.cpp +++ b/src/jit/regset.cpp @@ -2666,17 +2666,24 @@ void RegSet::rsUnspillRegPair(GenTreePtr tree, regMaskTP needReg, KeepReg keepRe if (rsIsTreeInReg(regHi, tree)) { - /* Temporarily lock the high part */ - - rsLockUsedReg(genRegMask(regHi)); + // Temporarily lock the high part if necessary. If this register is a multi-use register that is shared + // with another tree, the register may already be locked. + const regMaskTP regHiMask = genRegMask(regHi); + const bool lockReg = (rsMaskLock & regHiMask) == 0; + if (lockReg) + { + rsLockUsedReg(regHiMask); + } /* Pick a new home for the lower half */ regLo = rsUnspillOneReg(tree, regLo, keepReg, needReg); /* We can unlock the high part now */ - - rsUnlockUsedReg(genRegMask(regHi)); + if (lockReg) + { + rsUnlockUsedReg(regHiMask); + } } else { @@ -2700,17 +2707,24 @@ void RegSet::rsUnspillRegPair(GenTreePtr tree, regMaskTP needReg, KeepReg keepRe { regMaskTP regLoUsed; - /* Temporarily lock the low part so it doesnt get spilled */ - - rsLockReg(genRegMask(regLo), ®LoUsed); + // Temporarily lock the low part if necessary. If this register is a multi-use register that is shared + // with another tree, the register may already be locked. + const regMaskTP regLoMask = genRegMask(regLo); + const bool lockReg = (rsMaskLock & regLoMask) == 0; + if (lockReg) + { + rsLockReg(regLoMask, ®LoUsed); + } /* Pick a new home for the upper half */ regHi = rsUnspillOneReg(tree, regHi, keepReg, needReg); /* We can unlock the low register now */ - - rsUnlockReg(genRegMask(regLo), regLoUsed); + if (lockReg) + { + rsUnlockReg(regLoMask, regLoUsed); + } } else { -- 2.7.4