[llvm] c003bfb - [AMDGPU] Fix eliminateFrameIndex assertion when reusing the frame register. (#215182)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 12 02:38:56 PDT 2026


Author: Vikash Gupta
Date: 2026-08-12T15:08:51+05:30
New Revision: c003bfba61585dea16b6ad82b49d2e126d30df78

URL: https://github.com/llvm/llvm-project/commit/c003bfba61585dea16b6ad82b49d2e126d30df78
DIFF: https://github.com/llvm/llvm-project/commit/c003bfba61585dea16b6ad82b49d2e126d30df78.diff

LOG: [AMDGPU] Fix eliminateFrameIndex assertion when reusing the frame register. (#215182)

This is a follow-up patch that solves the crashing test in the #215180 

On a flat-scratch target, a frame index used by a VALU instruction with
a live frame register but no scavengeable SGPR entered the branch that
assumes no frame register exists, tripping `assert(!FrameReg && "there
is a frame register!")`.

Restore the `!FrameReg` term in the guard so this case falls through to
the existing path that reuses the frame register as the temporary
(offset folded in, then restored). The `!FrameReg` assertion is moved
into the SVS
fallback, where it actually holds.

Added: 
    

Modified: 
    llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
    llvm/test/CodeGen/AMDGPU/eliminate-frame-index-flat-scratch-frame-reg-no-sgpr.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
index a3d6509628d50..c661787b301c0 100644
--- a/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIRegisterInfo.cpp
@@ -3260,10 +3260,18 @@ bool SIRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MI,
                   : RS->scavengeRegisterBackwards(AMDGPU::SReg_32_XM0RegClass,
                                                   MI, false, 0, !UseSGPR);
 
-      if (!TmpSReg || (!TmpReg && !UseSGPR)) {
-        assert(!FrameReg && "there is a frame register!");
+      // If no SGPR was scavenged but a frame register is available, fall
+      // through to reuse it as the temporary (computed in place, restored
+      // after). Only bail out when there is no frame register, or a VGPR
+      // operand is needed but none could be scavenged.
+      if ((!TmpSReg && !FrameReg) || (!TmpReg && !UseSGPR)) {
         int SVOpcode = AMDGPU::getFlatScratchInstSVfromSS(MI->getOpcode());
         if (ST.hasFlatScratchSVSMode() && SVOpcode != -1) {
+          // SV form encodes only the offset in vaddr; an SS-form scratch op
+          // keeps its FI in the SGPR saddr, so this is only reached with no
+          // frame register.
+          assert(!FrameReg &&
+                 "SV-form fallback cannot encode a frame register");
           Register TmpVGPR = RS->scavengeRegisterBackwards(
               AMDGPU::VGPR_32RegClass, MI, false, 0, /*AllowSpill=*/true);
 

diff  --git a/llvm/test/CodeGen/AMDGPU/eliminate-frame-index-flat-scratch-frame-reg-no-sgpr.ll b/llvm/test/CodeGen/AMDGPU/eliminate-frame-index-flat-scratch-frame-reg-no-sgpr.ll
index b4a1b565032da..ffeb5ea399c3c 100644
--- a/llvm/test/CodeGen/AMDGPU/eliminate-frame-index-flat-scratch-frame-reg-no-sgpr.ll
+++ b/llvm/test/CodeGen/AMDGPU/eliminate-frame-index-flat-scratch-frame-reg-no-sgpr.ll
@@ -1,12 +1,12 @@
-; RUN: not --crash llc -mtriple=amdgpu9.42-amd-amdhsa -amdgpu-stress-sgpr=16 < %s 2>&1 | FileCheck %s
-; REQUIRES: asserts
+; RUN: llc -mtriple=amdgpu9.42-amd-amdhsa -amdgpu-stress-sgpr=16 < %s 2>&1 | FileCheck %s
 
-; NOTE: SIRegisterInfo::eliminateFrameIndex currently asserts on a
-; flat-scratch target when a frame index used by a VALU instruction reaches the
-; generic SGPR scavenging path, the function has a frame register, and no SGPR
-; is free for the scavenger. Control then enters the branch that assumes no
-; frame register exists: it asserts !FrameReg and its SVS lowering materializes
-; the address from the offset alone, without a frame-register term.
+; Verifies SIRegisterInfo::eliminateFrameIndex on a flat-scratch target: a frame
+; index used by a VALU instruction reaches the generic SGPR scavenging path.
+; When the function has a frame register but no SGPR is free for the scavenger,
+; the fix reuses the frame register as the temporary instead of taking the SVS
+; fallback (which assumes no frame register and previously asserted here). The
+; offset is folded into the frame register in place, the subtract reads it
+; directly as an SGPR source, and the frame register is restored afterwards.
 ;
 ; The reproducer needs all of following conditions:
 ;   1. A VALU frame-index user (V_SUB_CO_U32_e32 from the addrspacecast).
@@ -17,7 +17,7 @@
 ; The data dependency through %
diff  keeps every SGPR live across the subtract so
 ; the scheduler cannot free one up.
 
-; CHECK: there is a frame register!
+; CHECK-NOT: Cannot scavenge register in FI elimination!
 
 define fastcc i64 @no_scavengeable_sgpr_with_frame_register(
     ptr %p0, i32 %i0, i64 %l0, i64 %l1, i64 %l2,


        


More information about the llvm-commits mailing list