From 8330db998659c4e6410aba370b37e4304a517a2b Mon Sep 17 00:00:00 2001 From: Tymoteusz Wenerski Date: Thu, 7 Mar 2024 01:58:04 +0100 Subject: [PATCH] [RISC-V] Fix initReg usage in genPushCalleeSavedRegisters (#99353) --- src/coreclr/jit/codegenriscv64.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/codegenriscv64.cpp b/src/coreclr/jit/codegenriscv64.cpp index 7d9c33cc05dff..99c416faae25b 100644 --- a/src/coreclr/jit/codegenriscv64.cpp +++ b/src/coreclr/jit/codegenriscv64.cpp @@ -7782,6 +7782,11 @@ void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroe { assert(compiler->compGeneratingProlog); + // The 'initReg' could have been calculated as one of the callee-saved registers (let's say T0, T1 and T2 are in + // use, so the next possible register is S1, which should be callee-save register). This is fine, as long as we + // save callee-saved registers before using 'initReg' for the first time. Instead, we can use REG_SCRATCH + // beforehand. We don't care if REG_SCRATCH will be overwritten, so we'll skip 'RegZeroed check'. + // // Unlike on x86/x64, we can also push float registers to stack regMaskTP rsPushRegs = regSet.rsGetModifiedRegsMask() & RBM_CALLEE_SAVED; @@ -7894,11 +7899,11 @@ void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroe calleeSaveSPDelta = AlignUp((UINT)offset, STACK_ALIGN); offset = calleeSaveSPDelta - offset; - genStackPointerAdjustment(-calleeSaveSPDelta, initReg, pInitRegZeroed, /* reportUnwindData */ true); + genStackPointerAdjustment(-calleeSaveSPDelta, REG_SCRATCH, nullptr, /* reportUnwindData */ true); } else { - genStackPointerAdjustment(-totalFrameSize, initReg, pInitRegZeroed, /* reportUnwindData */ true); + genStackPointerAdjustment(-totalFrameSize, REG_SCRATCH, nullptr, /* reportUnwindData */ true); } } @@ -7907,6 +7912,8 @@ void CodeGen::genPushCalleeSavedRegisters(regNumber initReg, bool* pInitRegZeroe genSaveCalleeSavedRegistersHelp(rsPushRegs, offset, 0); offset += (int)(genCountBits(rsPushRegs) << 3); // each reg has 8 bytes + // From now on, we can safely use initReg. + emit->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_RA, REG_SPBASE, offset); compiler->unwindSaveReg(REG_RA, offset);