From d0ecf0d431dbdd47ea3d9b8c4cd82693be3110ac Mon Sep 17 00:00:00 2001 From: Andy Ayers Date: Wed, 15 Jul 2026 12:38:53 -0700 Subject: [PATCH] JIT/CSE: skip live-across-call CSEs with big footprint and few uses The default CSE heuristic is overly aggressive for live-across-call CSE candidates with high size cost and very cold uses. This change is the outcome of back-propagating information from various RL-derived and oracular models for CSEs onto our existing heuristic, along with benchmark-derived validations for x64/arm64. The majority of CSEs blocked (on xArch) are large immediates. Note we generally don't CSE these on xArch (see eg #129941) but some handle kinds are allowed. These are fairly "cheap" to rematerialize. Other cases are some indirs and CSE-able calls. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/coreclr/jit/optcse.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/coreclr/jit/optcse.cpp b/src/coreclr/jit/optcse.cpp index d14d9ebd570bb9..dd4c5f370264fe 100644 --- a/src/coreclr/jit/optcse.cpp +++ b/src/coreclr/jit/optcse.cpp @@ -4367,6 +4367,15 @@ bool CSE_Heuristic::PromotionCheck(CSE_Candidate* candidate) } #endif + // Reject CSE candidates that live across a call, have a non-trivial + // code footprint, and only a small (weighted) number of uses. + // + if ((CodeOptKind() != Compiler::SMALL_CODE) && candidate->LiveAcrossCall() && (candidate->Size() >= 8) && + (candidate->UseCount() <= 3)) + { + return false; + } + /* Our calculation is based on the following cost estimate formula