From faa2c1cdfdfdbd9dd78827a3fd52938264fed59d Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Mon, 20 Apr 2026 15:41:26 +0200 Subject: [PATCH 1/3] JIT: Disallow using float callee saves in x64 functions with patchpoints We do not restore these in the OSR methods so using these registers currently relies on the unwinder. We will have transitioning that does not use the unwinder soon so just disable using these registers. Since patchpoints only appear in tier0 methods it is not a big deal to avoid using these registers. --- src/coreclr/jit/lsra.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 9baa4f25bdf108..288a88b4e929b9 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -984,6 +984,21 @@ LinearScan::LinearScan(Compiler* theCompiler) } #endif // TARGET_AMD64 || TARGET_ARM64 +#ifdef TARGET_AMD64 + // On xarch the OSR method does not restore float registers from tier0 + // frame, so disallow using float callee saves in the tier0 method. + if (m_compiler->doesMethodHavePatchpoints() || m_compiler->doesMethodHavePartialCompilationPatchpoints()) + { +#if defined(UNIX_AMD64_ABI) + availableFloatRegs &= ~RBM_FLT_CALLEE_SAVED; + availableDoubleRegs &= ~RBM_FLT_CALLEE_SAVED; +#else + availableFloatRegs &= ~RBM_FLT_CALLEE_SAVED.GetFloatRegSet(); + availableDoubleRegs &= ~RBM_FLT_CALLEE_SAVED.GetFloatRegSet(); +#endif // UNIX_AMD64_ABI + } +#endif + #if defined(TARGET_AMD64) if (evexIsSupported) { From 493c885215f26a12753eb049a7c4df3839a6d2c9 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Mon, 20 Apr 2026 15:48:28 +0200 Subject: [PATCH 2/3] Feedback --- src/coreclr/jit/lsra.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 288a88b4e929b9..76e9badf7218cf 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -985,8 +985,8 @@ LinearScan::LinearScan(Compiler* theCompiler) #endif // TARGET_AMD64 || TARGET_ARM64 #ifdef TARGET_AMD64 - // On xarch the OSR method does not restore float registers from tier0 - // frame, so disallow using float callee saves in the tier0 method. + // On x64 the OSR method does not restore float registers from tier0 frame, + // so disallow using float callee saves in the tier0 method. if (m_compiler->doesMethodHavePatchpoints() || m_compiler->doesMethodHavePartialCompilationPatchpoints()) { #if defined(UNIX_AMD64_ABI) From 61bd3e4264488889c1c40bef50a1b879a59f09b8 Mon Sep 17 00:00:00 2001 From: Jakob Botsch Nielsen Date: Mon, 20 Apr 2026 16:43:42 +0200 Subject: [PATCH 3/3] Remove RBM_MSK_CALLEE_SAVED for future proofing --- src/coreclr/jit/lsra.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/lsra.cpp b/src/coreclr/jit/lsra.cpp index 76e9badf7218cf..d70f8c3ecbff52 100644 --- a/src/coreclr/jit/lsra.cpp +++ b/src/coreclr/jit/lsra.cpp @@ -985,8 +985,8 @@ LinearScan::LinearScan(Compiler* theCompiler) #endif // TARGET_AMD64 || TARGET_ARM64 #ifdef TARGET_AMD64 - // On x64 the OSR method does not restore float registers from tier0 frame, - // so disallow using float callee saves in the tier0 method. + // On x64 the OSR method does not restore float/mask registers from the + // tier0 frame, so disallow using those in the tier0 method. if (m_compiler->doesMethodHavePatchpoints() || m_compiler->doesMethodHavePartialCompilationPatchpoints()) { #if defined(UNIX_AMD64_ABI) @@ -996,6 +996,7 @@ LinearScan::LinearScan(Compiler* theCompiler) availableFloatRegs &= ~RBM_FLT_CALLEE_SAVED.GetFloatRegSet(); availableDoubleRegs &= ~RBM_FLT_CALLEE_SAVED.GetFloatRegSet(); #endif // UNIX_AMD64_ABI + availableMaskRegs &= ~RBM_MSK_CALLEE_SAVED; } #endif