[llvm] [AMDGPU] Scale the frame register in place when lowering scalar frame indices (PR #221972)
Christudasan Devadasan via llvm-commits
llvm-commits at lists.llvm.org
Thu Sep 10 01:56:38 PDT 2026
================
@@ -3419,11 +3419,40 @@ bool SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
bool IsCopy = MI->getOpcode() == AMDGPU::V_MOV_B32_e32 ||
MI->getOpcode() == AMDGPU::V_MOV_B32_e64 ||
MI->getOpcode() == AMDGPU::S_MOV_B32;
- Register ResultReg =
- IsCopy ? MI->getOperand(0).getReg()
- : RS->scavengeRegisterBackwards(*RC, MI, false, 0);
int64_t Offset = FrameInfo.getObjectOffset(Index);
+ int64_t ScaledOffset = -Offset * ST.getWavefrontSize();
+
+ // Scaling FrameReg in place is the last resort when there is nothing to
+ // scavenge. It has to be undone after MI, which is only possible while MI
+ // does not use FrameReg for anything besides the frame index, and while
+ // the offset can be folded back in wave space. A second frame index on MI
+ // would be lowered while FrameReg is still scaled, so keep away from it.
+ bool HasOneFrameIndex =
+ llvm::count_if(MI->operands(), [](const MachineOperand &MO) {
+ return MO.isFI();
+ }) == 1;
+ bool CanUseFrameRegAsScratch =
+ IsSALU && !LiveSCC && FrameReg && HasOneFrameIndex &&
+ !MI->readsRegister(FrameReg, this) &&
+ !MI->modifiesRegister(FrameReg, this) && isInt<32>(ScaledOffset);
+
+ bool RestoreFrameReg = false;
+ Register ResultReg;
+ if (IsCopy) {
+ ResultReg = MI->getOperand(0).getReg();
+ } else {
+ ResultReg = RS->scavengeRegisterBackwards(*RC, MI, false, 0,
+ /*AllowSpill=*/false);
+ if (!ResultReg && CanUseFrameRegAsScratch) {
+ // Spilling an SGPR here instead would flip EXEC with S_NOT, and that
+ // clobbers the SCC MI may be defining for a later use.
+ ResultReg = FrameReg;
+ RestoreFrameReg = true;
+ } else if (!ResultReg) {
+ ResultReg = RS->scavengeRegisterBackwards(*RC, MI, false, 0);
+ }
----------------
cdevadas wrote:
Use of !ResultReg in the `if` above and again in the `else-if` here is confusing.
```
if (!ResultReg) {
// Scavenge failed, try alternatives
if (CanUseFrameRegAsScratch) {
// Use FrameReg to avoid SCC clobber from emergency spill
ResultReg = FrameReg;
RestoreFrameReg = true;
} else {
// Last resort: emergency spill (may clobber SCC)
ResultReg = RS->scavengeRegisterBackwards(*RC, MI, false, 0);
}
}
```
https://github.com/llvm/llvm-project/pull/221972
More information about the llvm-commits
mailing list