[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