Handle unspilling part of a multi-use reg with FREE_REG
authorBruce Forstall <brucefo@microsoft.com>
Tue, 1 Aug 2017 00:28:04 +0000 (17:28 -0700)
committerBruce Forstall <brucefo@microsoft.com>
Tue, 1 Aug 2017 00:28:04 +0000 (17:28 -0700)
If rsUnspillOneReg() is called with willKeepNewReg==FREE_REG
(indicating the unspilled value will be free on return),
and the reg to unspill is multi-use, then we were releasing the
underlying temp incorrectly, since the temp still contains the
other multi-use spilled values, which will be subsequently
unspilled.

This occurred in a very large, JitStressRegs=1/JitStress=1 test case.

Fixes #12911

src/jit/regset.cpp

index 7204663..bc6bde9 100644 (file)
@@ -2336,9 +2336,13 @@ regNumber RegSet::rsUnspillOneReg(GenTreePtr tree, regNumber oldReg, KeepReg wil
             rsMaskMult |= genRegMask(newReg);
     }
 
-    /* Free the temp, it's no longer used */
-
-    m_rsCompiler->tmpRlsTemp(temp);
+    if (!multiUsed || (willKeepNewReg == KEEP_REG))
+    {
+        // Free the temp, it's no longer used.
+        // For multi-used regs that aren't (willKeepNewReg == KEEP_REG), we didn't unspill everything, so
+        // we need to leave the temp for future unspilling.
+        m_rsCompiler->tmpRlsTemp(temp);
+    }
 
     return newReg;
 }