Reworking of #37969. Block LSRA from using R2 around the profiler leave
callback, but don't kill GC refs in R2, since late codegen will use
R2 to temporarily hold return values around the callback.
Fixes #37223.
Co-authored-by: Carol Eidt <carol.eidt@microsoft.com>
break;
case CORINFO_HELP_PROF_FCN_LEAVE:
+#if defined(TARGET_ARM)
+ // profiler scratch remains gc live
+ result = RBM_PROFILER_LEAVE_TRASH & ~RBM_PROFILER_RET_SCRATCH;
+#else
result = RBM_PROFILER_LEAVE_TRASH;
+#endif
break;
case CORINFO_HELP_PROF_FCN_TAILCALL:
case GT_RETURN:
srcCount = BuildReturn(tree);
+ killMask = getKillSetForReturn();
+ BuildDefsWithKills(tree, 0, RBM_NONE, killMask);
break;
case GT_RETFILT:
// The registers trashed by profiler enter/leave/tailcall hook
// See vm\arm\asmhelpers.asm for more details.
#define RBM_PROFILER_ENTER_TRASH RBM_NONE
- #define RBM_PROFILER_LEAVE_TRASH RBM_NONE
+ // While REG_PROFILER_RET_SCRATCH is not trashed by the method, the register allocator must
+ // consider it killed by the return.
+ #define RBM_PROFILER_LEAVE_TRASH RBM_PROFILER_RET_SCRATCH
#define RBM_PROFILER_TAILCALL_TRASH RBM_NONE
// Which register are int and long values returned in ?