[llvm] [AMDGPU] Fix crash with dead frame indices in debug values (PR #183297)

Sergio Afonso via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 31 02:21:58 PDT 2026


https://github.com/skatrak updated https://github.com/llvm/llvm-project/pull/183297

>From 1a6ad8d44685b38f3dec0cf722d266a51c71749b Mon Sep 17 00:00:00 2001
From: Sergio Afonso <Sergio.AfonsoFumero at amd.com>
Date: Wed, 25 Feb 2026 12:56:40 +0000
Subject: [PATCH 1/7] [AMDGPU] Fix crash with dead frame indices in debug
 values

When spill slots are eliminated (VGPR-to-AGPR, SGPR-to-VGPR lanes),
debug values referencing these frame indices were not always properly
cleaned up. This caused an assertion failure in getObjectOffset() when
PrologEpilogInserter tried to access the offset of a dead frame object.

The existing debug fixup code in SIFrameLowering and SILowerSGPRSpills
had two limitations:
1. It only checked one operand position, but DBG_VALUE_LIST instructions
   can have multiple debug operands with frame indices.
2. It didn't handle all types of dead frame indices uniformly.

Fix by centralizing debug info cleanup in removeDeadFrameIndices(), which
already knows all frame indices being removed. This iterates over all
debug operands using MI.debug_operands().

Assisted-by: Claude Code.
---
 llvm/lib/Target/AMDGPU/SIFrameLowering.cpp    | 25 +----------
 llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp  | 23 ++--------
 .../Target/AMDGPU/SIMachineFunctionInfo.cpp   | 36 ++++++++++++++--
 .../lib/Target/AMDGPU/SIMachineFunctionInfo.h |  5 ++-
 .../AMDGPU/dead-frame-index-dbg-value.ll      | 43 +++++++++++++++++++
 5 files changed, 82 insertions(+), 50 deletions(-)
 create mode 100644 llvm/test/CodeGen/AMDGPU/dead-frame-index-dbg-value.ll

diff --git a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
index 4a62af56fd8e5..6da73415deb77 100644
--- a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
@@ -1478,14 +1478,9 @@ void SIFrameLowering::processFunctionBeforeFrameFinalized(
     BitVector SpillFIs(MFI.getObjectIndexEnd(), false);
     BitVector NonVGPRSpillFIs(MFI.getObjectIndexEnd(), false);
 
-    bool SeenDbgInstr = false;
-
     for (MachineBasicBlock &MBB : MF) {
       for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
         int FrameIndex;
-        if (MI.isDebugInstr())
-          SeenDbgInstr = true;
-
         if (TII->isVGPRSpill(MI)) {
           // Try to eliminate stack used by VGPR spills before frame
           // finalization.
@@ -1524,24 +1519,6 @@ void SIFrameLowering::processFunctionBeforeFrameFinalized(
         MBB.addLiveIn(Reg);
 
       MBB.sortUniqueLiveIns();
-
-      if (!SpillFIs.empty() && SeenDbgInstr) {
-        // FIXME: The dead frame indices are replaced with a null register from
-        // the debug value instructions. We should instead, update it with the
-        // correct register value. But not sure the register value alone is
-        for (MachineInstr &MI : MBB) {
-          if (MI.isDebugValue()) {
-            uint32_t StackOperandIdx = MI.isDebugValueList() ? 2 : 0;
-            if (MI.getOperand(StackOperandIdx).isFI() &&
-                !MFI.isFixedObjectIndex(
-                    MI.getOperand(StackOperandIdx).getIndex()) &&
-                SpillFIs[MI.getOperand(StackOperandIdx).getIndex()]) {
-              MI.getOperand(StackOperandIdx)
-                  .ChangeToRegister(Register(), false /*isDef*/);
-            }
-          }
-        }
-      }
     }
   }
 
@@ -1549,7 +1526,7 @@ void SIFrameLowering::processFunctionBeforeFrameFinalized(
   // can. Any remaining SGPR spills will go to memory, so move them back to the
   // default stack.
   bool HaveSGPRToVMemSpill =
-      FuncInfo->removeDeadFrameIndices(MFI, /*ResetSGPRSpillStackIDs*/ true);
+      FuncInfo->removeDeadFrameIndices(MF, /*ResetSGPRSpillStackIDs*/ true);
   assert(allSGPRSpillsAreDead(MF) &&
          "SGPR spill should have been removed in SILowerSGPRSpills");
 
diff --git a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
index cbd08f0fb5dff..d54f4eeb3c2b0 100644
--- a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
+++ b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
@@ -524,31 +524,14 @@ bool SILowerSGPRSpills::run(MachineFunction &MF) {
       FuncInfo->updateNonWWMRegMask(NonWwmRegMask);
     }
 
-    for (MachineBasicBlock &MBB : MF) {
-      // FIXME: The dead frame indices are replaced with a null register from
-      // the debug value instructions. We should instead, update it with the
-      // correct register value. But not sure the register value alone is
-      // adequate to lower the DIExpression. It should be worked out later.
-      for (MachineInstr &MI : MBB) {
-        if (MI.isDebugValue()) {
-          uint32_t StackOperandIdx = MI.isDebugValueList() ? 2 : 0;
-          if (MI.getOperand(StackOperandIdx).isFI() &&
-              !MFI.isFixedObjectIndex(
-                  MI.getOperand(StackOperandIdx).getIndex()) &&
-              SpillFIs[MI.getOperand(StackOperandIdx).getIndex()]) {
-            MI.getOperand(StackOperandIdx)
-                .ChangeToRegister(Register(), false /*isDef*/);
-          }
-        }
-      }
-    }
-
     // All those frame indices which are dead by now should be removed from the
     // function frame. Otherwise, there is a side effect such as re-mapping of
     // free frame index ids by the later pass(es) like "stack slot coloring"
     // which in turn could mess-up with the book keeping of "frame index to VGPR
     // lane".
-    FuncInfo->removeDeadFrameIndices(MFI, /*ResetSGPRSpillStackIDs*/ false);
+    // This also clears debug value operands that reference the removed frame
+    // indices.
+    FuncInfo->removeDeadFrameIndices(MF, /*ResetSGPRSpillStackIDs*/ false);
 
     MadeChange = true;
   }
diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
index 25a28ec471913..e78fc716ba593 100644
--- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
@@ -12,12 +12,13 @@
 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
 #include "SIRegisterInfo.h"
 #include "Utils/AMDGPUBaseInfo.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/CodeGen/LiveIntervals.h"
-#include "llvm/CodeGen/MIRParser/MIParser.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/MIRParser/MIParser.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Function.h"
@@ -565,8 +566,13 @@ bool SIMachineFunctionInfo::allocateVGPRSpillToAGPR(MachineFunction &MF,
   return Spill.FullyAllocated;
 }
 
-bool SIMachineFunctionInfo::removeDeadFrameIndices(
-    MachineFrameInfo &MFI, bool ResetSGPRSpillStackIDs) {
+bool SIMachineFunctionInfo::removeDeadFrameIndices(MachineFunction &MF,
+                                                   bool ResetSGPRSpillStackIDs) {
+  MachineFrameInfo &MFI = MF.getFrameInfo();
+
+  // Collect all frame indices that will be removed so we can clear debug info.
+  SmallDenseSet<int, 8> DeadFIs;
+
   // Remove dead frame indices from function frame, however keep FP & BP since
   // spills for them haven't been inserted yet. And also make sure to remove the
   // frame indices from `SGPRSpillsToVirtualVGPRLanes` data structure,
@@ -574,6 +580,7 @@ bool SIMachineFunctionInfo::removeDeadFrameIndices(
   // any re-mapping of freed frame indices by later pass(es) like "stack slot
   // coloring".
   for (auto &R : make_early_inc_range(SGPRSpillsToVirtualVGPRLanes)) {
+    DeadFIs.insert(R.first);
     MFI.RemoveStackObject(R.first);
     SGPRSpillsToVirtualVGPRLanes.erase(R.first);
   }
@@ -582,6 +589,7 @@ bool SIMachineFunctionInfo::removeDeadFrameIndices(
   // VGPR lanes during SILowerSGPRSpills pass.
   if (!ResetSGPRSpillStackIDs) {
     for (auto &R : make_early_inc_range(SGPRSpillsToPhysicalVGPRLanes)) {
+      DeadFIs.insert(R.first);
       MFI.RemoveStackObject(R.first);
       SGPRSpillsToPhysicalVGPRLanes.erase(R.first);
     }
@@ -603,8 +611,28 @@ bool SIMachineFunctionInfo::removeDeadFrameIndices(
   }
 
   for (auto &R : VGPRToAGPRSpills) {
-    if (R.second.IsDead)
+    if (R.second.IsDead) {
+      DeadFIs.insert(R.first);
       MFI.RemoveStackObject(R.first);
+    }
+  }
+
+  // Clear debug value operands that reference dead frame indices. The spill
+  // values are no longer available in memory, so we replace the operand with
+  // a null register to indicate the value is unavailable.
+  // FIXME: We should instead update the debug value with the correct register
+  // value if possible.
+  if (!DeadFIs.empty()) {
+    for (MachineBasicBlock &MBB : MF) {
+      for (MachineInstr &MI : MBB) {
+        if (MI.isDebugValue()) {
+          for (MachineOperand &Op : MI.debug_operands()) {
+            if (Op.isFI() && DeadFIs.contains(Op.getIndex()))
+              Op.ChangeToRegister(Register(), false /*isDef*/);
+          }
+        }
+      }
+    }
   }
 
   return HaveSGPRToMemory;
diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
index 617862db8f506..6f51231634bcd 100644
--- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
@@ -832,8 +832,9 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunction,
   bool allocateVGPRSpillToAGPR(MachineFunction &MF, int FI, bool isAGPRtoVGPR);
 
   /// If \p ResetSGPRSpillStackIDs is true, reset the stack ID from sgpr-spill
-  /// to the default stack.
-  bool removeDeadFrameIndices(MachineFrameInfo &MFI,
+  /// to the default stack. Also clears any debug value operands that reference
+  /// the removed frame indices.
+  bool removeDeadFrameIndices(MachineFunction &MF,
                               bool ResetSGPRSpillStackIDs);
 
   int getScavengeFI(MachineFrameInfo &MFI, const SIRegisterInfo &TRI);
diff --git a/llvm/test/CodeGen/AMDGPU/dead-frame-index-dbg-value.ll b/llvm/test/CodeGen/AMDGPU/dead-frame-index-dbg-value.ll
new file mode 100644
index 0000000000000..1d4a808cb414c
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/dead-frame-index-dbg-value.ll
@@ -0,0 +1,43 @@
+; RUN: llc -O0 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 < %s
+; RUN: llc -O0 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 < %s
+
+; Check that debug values referencing eliminated frame indices don't crash.
+; The AMDGPU backend can eliminate spill slots during frame finalization
+; (e.g., SGPR spills to VGPR lanes). Debug values referencing these eliminated
+; frame indices need to be cleaned up to avoid assertions in PrologEpilogInserter.
+
+target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
+target triple = "amdgcn-amd-amdhsa"
+
+%struct.Buffer = type { [8 x i64] }
+
+; Test case with DIArgList and DW_OP_xderef that triggered the original crash.
+; The dbg_value references a computed address that may involve frame indices
+; from eliminated spill slots.
+define ptr @test_dbg_value_dead_frame_idx() !dbg !10 {
+entry:
+  %idx = zext i32 0 to i64
+  br label %body
+
+body:
+  #dbg_value(!DIArgList(ptr null, i64 %idx), !15, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_constu, 64, DW_OP_mul, DW_OP_plus, DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef, DW_OP_stack_value), !17)
+  %ptr = getelementptr %struct.Buffer, ptr null, i64 %idx
+  ret ptr %ptr
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3, !4}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
+!1 = !DIFile(filename: "test.cpp", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 1, !"amdhsa_code_object_version", i32 500}
+!5 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed)
+!6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64, dwarfAddressSpace: 1)
+!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Buffer", file: !1, line: 1, size: 512, flags: DIFlagTypePassByValue, elements: !2)
+!10 = distinct !DISubprogram(name: "test_dbg_value_dead_frame_idx", scope: !1, file: !1, line: 10, type: !11, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
+!11 = !DISubroutineType(types: !12)
+!12 = !{!6}
+!15 = !DILocalVariable(name: "slot", scope: !10, file: !1, line: 11, type: !6)
+!17 = !DILocation(line: 11, column: 1, scope: !10)

>From 0f1954a84fe883a03de94c546ae89ba032c812a6 Mon Sep 17 00:00:00 2001
From: Sergio Afonso <Sergio.AfonsoFumero at amd.com>
Date: Wed, 25 Feb 2026 13:27:45 +0000
Subject: [PATCH 2/7] format

---
 llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp | 6 +++---
 llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h   | 3 +--
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
index e78fc716ba593..12f173a9cb4f0 100644
--- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
@@ -14,11 +14,11 @@
 #include "Utils/AMDGPUBaseInfo.h"
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/CodeGen/LiveIntervals.h"
+#include "llvm/CodeGen/MIRParser/MIParser.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
-#include "llvm/CodeGen/MIRParser/MIParser.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/DiagnosticInfo.h"
 #include "llvm/IR/Function.h"
@@ -566,8 +566,8 @@ bool SIMachineFunctionInfo::allocateVGPRSpillToAGPR(MachineFunction &MF,
   return Spill.FullyAllocated;
 }
 
-bool SIMachineFunctionInfo::removeDeadFrameIndices(MachineFunction &MF,
-                                                   bool ResetSGPRSpillStackIDs) {
+bool SIMachineFunctionInfo::removeDeadFrameIndices(
+    MachineFunction &MF, bool ResetSGPRSpillStackIDs) {
   MachineFrameInfo &MFI = MF.getFrameInfo();
 
   // Collect all frame indices that will be removed so we can clear debug info.
diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
index 6f51231634bcd..daae0225611d3 100644
--- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
@@ -834,8 +834,7 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunction,
   /// If \p ResetSGPRSpillStackIDs is true, reset the stack ID from sgpr-spill
   /// to the default stack. Also clears any debug value operands that reference
   /// the removed frame indices.
-  bool removeDeadFrameIndices(MachineFunction &MF,
-                              bool ResetSGPRSpillStackIDs);
+  bool removeDeadFrameIndices(MachineFunction &MF, bool ResetSGPRSpillStackIDs);
 
   int getScavengeFI(MachineFrameInfo &MFI, const SIRegisterInfo &TRI);
   std::optional<int> getOptionalScavengeFI() const { return ScavengeFI; }

>From 8290fa7667b288888e301227e3e29491ac5cd2d3 Mon Sep 17 00:00:00 2001
From: Sergio Afonso <Sergio.AfonsoFumero at amd.com>
Date: Thu, 26 Feb 2026 12:05:40 +0000
Subject: [PATCH 3/7] address review comments

---
 llvm/lib/Target/AMDGPU/SIFrameLowering.cpp    | 23 ++++++++++++-
 llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp  | 21 ++++++++++--
 .../Target/AMDGPU/SIMachineFunctionInfo.cpp   | 32 ++-----------------
 .../lib/Target/AMDGPU/SIMachineFunctionInfo.h |  6 ++--
 .../AMDGPU/dead-frame-index-dbg-value.ll      | 29 +++++++----------
 5 files changed, 56 insertions(+), 55 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
index 6da73415deb77..857795b2eba74 100644
--- a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
@@ -1478,9 +1478,14 @@ void SIFrameLowering::processFunctionBeforeFrameFinalized(
     BitVector SpillFIs(MFI.getObjectIndexEnd(), false);
     BitVector NonVGPRSpillFIs(MFI.getObjectIndexEnd(), false);
 
+    bool SeenDbgInstr = false;
+
     for (MachineBasicBlock &MBB : MF) {
       for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
         int FrameIndex;
+        if (MI.isDebugInstr())
+          SeenDbgInstr = true;
+
         if (TII->isVGPRSpill(MI)) {
           // Try to eliminate stack used by VGPR spills before frame
           // finalization.
@@ -1519,6 +1524,22 @@ void SIFrameLowering::processFunctionBeforeFrameFinalized(
         MBB.addLiveIn(Reg);
 
       MBB.sortUniqueLiveIns();
+
+      if (!SpillFIs.empty() && SeenDbgInstr) {
+        // FIXME: The dead frame indices are replaced with a null register from
+        // the debug value instructions. We should instead, update it with the
+        // correct register value. But not sure the register value alone is
+        for (MachineInstr &MI : MBB) {
+          if (MI.isDebugValue()) {
+            for (MachineOperand &Op : MI.debug_operands()) {
+              if (Op.isFI() && !MFI.isFixedObjectIndex(Op.getIndex()) &&
+                  SpillFIs[Op.getIndex()]) {
+                Op.ChangeToRegister(Register(), false /*isDef*/);
+              }
+            }
+          }
+        }
+      }
     }
   }
 
@@ -1526,7 +1547,7 @@ void SIFrameLowering::processFunctionBeforeFrameFinalized(
   // can. Any remaining SGPR spills will go to memory, so move them back to the
   // default stack.
   bool HaveSGPRToVMemSpill =
-      FuncInfo->removeDeadFrameIndices(MF, /*ResetSGPRSpillStackIDs*/ true);
+      FuncInfo->removeDeadFrameIndices(MFI, /*ResetSGPRSpillStackIDs*/ true);
   assert(allSGPRSpillsAreDead(MF) &&
          "SGPR spill should have been removed in SILowerSGPRSpills");
 
diff --git a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
index d54f4eeb3c2b0..b250310cfaa66 100644
--- a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
+++ b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
@@ -524,14 +524,29 @@ bool SILowerSGPRSpills::run(MachineFunction &MF) {
       FuncInfo->updateNonWWMRegMask(NonWwmRegMask);
     }
 
+    for (MachineBasicBlock &MBB : MF) {
+      // FIXME: The dead frame indices are replaced with a null register from
+      // the debug value instructions. We should instead, update it with the
+      // correct register value. But not sure the register value alone is
+      // adequate to lower the DIExpression. It should be worked out later.
+      for (MachineInstr &MI : MBB) {
+        if (MI.isDebugValue()) {
+          for (MachineOperand &Op : MI.debug_operands()) {
+            if (Op.isFI() && !MFI.isFixedObjectIndex(Op.getIndex()) &&
+                SpillFIs[Op.getIndex()]) {
+              Op.ChangeToRegister(Register(), false /*isDef*/);
+            }
+          }
+        }
+      }
+    }
+
     // All those frame indices which are dead by now should be removed from the
     // function frame. Otherwise, there is a side effect such as re-mapping of
     // free frame index ids by the later pass(es) like "stack slot coloring"
     // which in turn could mess-up with the book keeping of "frame index to VGPR
     // lane".
-    // This also clears debug value operands that reference the removed frame
-    // indices.
-    FuncInfo->removeDeadFrameIndices(MF, /*ResetSGPRSpillStackIDs*/ false);
+    FuncInfo->removeDeadFrameIndices(MFI, /*ResetSGPRSpillStackIDs*/ false);
 
     MadeChange = true;
   }
diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
index 12f173a9cb4f0..25a28ec471913 100644
--- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.cpp
@@ -12,7 +12,6 @@
 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
 #include "SIRegisterInfo.h"
 #include "Utils/AMDGPUBaseInfo.h"
-#include "llvm/ADT/DenseSet.h"
 #include "llvm/CodeGen/LiveIntervals.h"
 #include "llvm/CodeGen/MIRParser/MIParser.h"
 #include "llvm/CodeGen/MachineBasicBlock.h"
@@ -567,12 +566,7 @@ bool SIMachineFunctionInfo::allocateVGPRSpillToAGPR(MachineFunction &MF,
 }
 
 bool SIMachineFunctionInfo::removeDeadFrameIndices(
-    MachineFunction &MF, bool ResetSGPRSpillStackIDs) {
-  MachineFrameInfo &MFI = MF.getFrameInfo();
-
-  // Collect all frame indices that will be removed so we can clear debug info.
-  SmallDenseSet<int, 8> DeadFIs;
-
+    MachineFrameInfo &MFI, bool ResetSGPRSpillStackIDs) {
   // Remove dead frame indices from function frame, however keep FP & BP since
   // spills for them haven't been inserted yet. And also make sure to remove the
   // frame indices from `SGPRSpillsToVirtualVGPRLanes` data structure,
@@ -580,7 +574,6 @@ bool SIMachineFunctionInfo::removeDeadFrameIndices(
   // any re-mapping of freed frame indices by later pass(es) like "stack slot
   // coloring".
   for (auto &R : make_early_inc_range(SGPRSpillsToVirtualVGPRLanes)) {
-    DeadFIs.insert(R.first);
     MFI.RemoveStackObject(R.first);
     SGPRSpillsToVirtualVGPRLanes.erase(R.first);
   }
@@ -589,7 +582,6 @@ bool SIMachineFunctionInfo::removeDeadFrameIndices(
   // VGPR lanes during SILowerSGPRSpills pass.
   if (!ResetSGPRSpillStackIDs) {
     for (auto &R : make_early_inc_range(SGPRSpillsToPhysicalVGPRLanes)) {
-      DeadFIs.insert(R.first);
       MFI.RemoveStackObject(R.first);
       SGPRSpillsToPhysicalVGPRLanes.erase(R.first);
     }
@@ -611,28 +603,8 @@ bool SIMachineFunctionInfo::removeDeadFrameIndices(
   }
 
   for (auto &R : VGPRToAGPRSpills) {
-    if (R.second.IsDead) {
-      DeadFIs.insert(R.first);
+    if (R.second.IsDead)
       MFI.RemoveStackObject(R.first);
-    }
-  }
-
-  // Clear debug value operands that reference dead frame indices. The spill
-  // values are no longer available in memory, so we replace the operand with
-  // a null register to indicate the value is unavailable.
-  // FIXME: We should instead update the debug value with the correct register
-  // value if possible.
-  if (!DeadFIs.empty()) {
-    for (MachineBasicBlock &MBB : MF) {
-      for (MachineInstr &MI : MBB) {
-        if (MI.isDebugValue()) {
-          for (MachineOperand &Op : MI.debug_operands()) {
-            if (Op.isFI() && DeadFIs.contains(Op.getIndex()))
-              Op.ChangeToRegister(Register(), false /*isDef*/);
-          }
-        }
-      }
-    }
   }
 
   return HaveSGPRToMemory;
diff --git a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
index daae0225611d3..617862db8f506 100644
--- a/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIMachineFunctionInfo.h
@@ -832,9 +832,9 @@ class SIMachineFunctionInfo final : public AMDGPUMachineFunction,
   bool allocateVGPRSpillToAGPR(MachineFunction &MF, int FI, bool isAGPRtoVGPR);
 
   /// If \p ResetSGPRSpillStackIDs is true, reset the stack ID from sgpr-spill
-  /// to the default stack. Also clears any debug value operands that reference
-  /// the removed frame indices.
-  bool removeDeadFrameIndices(MachineFunction &MF, bool ResetSGPRSpillStackIDs);
+  /// to the default stack.
+  bool removeDeadFrameIndices(MachineFrameInfo &MFI,
+                              bool ResetSGPRSpillStackIDs);
 
   int getScavengeFI(MachineFrameInfo &MFI, const SIRegisterInfo &TRI);
   std::optional<int> getOptionalScavengeFI() const { return ScavengeFI; }
diff --git a/llvm/test/CodeGen/AMDGPU/dead-frame-index-dbg-value.ll b/llvm/test/CodeGen/AMDGPU/dead-frame-index-dbg-value.ll
index 1d4a808cb414c..235c4414ba64e 100644
--- a/llvm/test/CodeGen/AMDGPU/dead-frame-index-dbg-value.ll
+++ b/llvm/test/CodeGen/AMDGPU/dead-frame-index-dbg-value.ll
@@ -1,28 +1,22 @@
-; RUN: llc -O0 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 < %s
-; RUN: llc -O0 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 < %s
+; RUN: llc -O0 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 < %s | FileCheck %s
+; RUN: llc -O0 -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 < %s | FileCheck %s
 
 ; Check that debug values referencing eliminated frame indices don't crash.
 ; The AMDGPU backend can eliminate spill slots during frame finalization
 ; (e.g., SGPR spills to VGPR lanes). Debug values referencing these eliminated
 ; frame indices need to be cleaned up to avoid assertions in PrologEpilogInserter.
 
-target datalayout = "e-m:e-p:64:64-p1:64:64-p2:32:32-p3:32:32-p4:64:64-p5:32:32-p6:32:32-p7:160:256:256:32-p8:128:128:128:48-p9:192:256:256:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64-S32-A5-G1-ni:7:8:9"
-target triple = "amdgcn-amd-amdhsa"
-
 %struct.Buffer = type { [8 x i64] }
 
-; Test case with DIArgList and DW_OP_xderef that triggered the original crash.
-; The dbg_value references a computed address that may involve frame indices
-; from eliminated spill slots.
-define ptr @test_dbg_value_dead_frame_idx() !dbg !10 {
+; CHECK-LABEL: test_dbg_value_dead_frame_idx:
+; CHECK: ;DEBUG_VALUE: test_dbg_value_dead_frame_idx:slot <- [DW_OP_LLVM_arg 0, DW_OP_LLVM_arg 1, DW_OP_constu 64, DW_OP_mul, DW_OP_plus, DW_OP_stack_value] {{.*}}
+; CHECK: s_endpgm
+define amdgpu_kernel void @test_dbg_value_dead_frame_idx(ptr addrspace(1) %out, i64 %idx) !dbg !10 {
 entry:
-  %idx = zext i32 0 to i64
-  br label %body
-
-body:
-  #dbg_value(!DIArgList(ptr null, i64 %idx), !15, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_constu, 64, DW_OP_mul, DW_OP_plus, DW_OP_constu, 1, DW_OP_swap, DW_OP_xderef, DW_OP_stack_value), !17)
-  %ptr = getelementptr %struct.Buffer, ptr null, i64 %idx
-  ret ptr %ptr
+  #dbg_value(!DIArgList(ptr addrspace(1) %out, i64 %idx), !15, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_constu, 64, DW_OP_mul, DW_OP_plus, DW_OP_stack_value), !17)
+  %ptr = getelementptr %struct.Buffer, ptr addrspace(1) %out, i64 %idx
+  store i64 0, ptr addrspace(1) %ptr, align 8
+  ret void
 }
 
 !llvm.dbg.cu = !{!0}
@@ -33,11 +27,10 @@ body:
 !2 = !{}
 !3 = !{i32 2, !"Debug Info Version", i32 3}
 !4 = !{i32 1, !"amdhsa_code_object_version", i32 500}
-!5 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed)
 !6 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 64, dwarfAddressSpace: 1)
 !7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "Buffer", file: !1, line: 1, size: 512, flags: DIFlagTypePassByValue, elements: !2)
 !10 = distinct !DISubprogram(name: "test_dbg_value_dead_frame_idx", scope: !1, file: !1, line: 10, type: !11, scopeLine: 10, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0)
 !11 = !DISubroutineType(types: !12)
-!12 = !{!6}
+!12 = !{null, !6}
 !15 = !DILocalVariable(name: "slot", scope: !10, file: !1, line: 11, type: !6)
 !17 = !DILocation(line: 11, column: 1, scope: !10)

>From 27dd9c4b847d7fb72366c39e090027ed63d7075a Mon Sep 17 00:00:00 2001
From: Sergio Afonso <Sergio.AfonsoFumero at amd.com>
Date: Wed, 25 Mar 2026 14:40:49 +0000
Subject: [PATCH 4/7] refactor duplicated code into a helper function

---
 llvm/lib/Target/AMDGPU/CMakeLists.txt        |  1 +
 llvm/lib/Target/AMDGPU/SIFrameLowering.cpp   | 20 +++--------
 llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp | 18 ++--------
 llvm/lib/Target/AMDGPU/SISpillUtils.cpp      | 35 ++++++++++++++++++++
 llvm/lib/Target/AMDGPU/SISpillUtils.h        | 23 +++++++++++++
 5 files changed, 65 insertions(+), 32 deletions(-)
 create mode 100644 llvm/lib/Target/AMDGPU/SISpillUtils.cpp
 create mode 100644 llvm/lib/Target/AMDGPU/SISpillUtils.h

diff --git a/llvm/lib/Target/AMDGPU/CMakeLists.txt b/llvm/lib/Target/AMDGPU/CMakeLists.txt
index ae684a58cfd26..7bf72227ea245 100644
--- a/llvm/lib/Target/AMDGPU/CMakeLists.txt
+++ b/llvm/lib/Target/AMDGPU/CMakeLists.txt
@@ -171,6 +171,7 @@ add_llvm_target(AMDGPUCodeGen
   SILowerWWMCopies.cpp
   SILowerSGPRSpills.cpp
   SIMachineFunctionInfo.cpp
+  SISpillUtils.cpp
   SIMachineScheduler.cpp
   SIMemoryLegalizer.cpp
   SIModeRegister.cpp
diff --git a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
index 857795b2eba74..a329cec761ce1 100644
--- a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
@@ -12,6 +12,7 @@
 #include "GCNSubtarget.h"
 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
 #include "SIMachineFunctionInfo.h"
+#include "SISpillUtils.h"
 #include "llvm/CodeGen/LiveRegUnits.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/RegisterScavenging.h"
@@ -1524,23 +1525,10 @@ void SIFrameLowering::processFunctionBeforeFrameFinalized(
         MBB.addLiveIn(Reg);
 
       MBB.sortUniqueLiveIns();
-
-      if (!SpillFIs.empty() && SeenDbgInstr) {
-        // FIXME: The dead frame indices are replaced with a null register from
-        // the debug value instructions. We should instead, update it with the
-        // correct register value. But not sure the register value alone is
-        for (MachineInstr &MI : MBB) {
-          if (MI.isDebugValue()) {
-            for (MachineOperand &Op : MI.debug_operands()) {
-              if (Op.isFI() && !MFI.isFixedObjectIndex(Op.getIndex()) &&
-                  SpillFIs[Op.getIndex()]) {
-                Op.ChangeToRegister(Register(), false /*isDef*/);
-              }
-            }
-          }
-        }
-      }
     }
+
+    if (!SpillFIs.empty() && SeenDbgInstr)
+      clearDebugInfoForSpillFIs(MF, SpillFIs);
   }
 
   // At this point we've already allocated all spilled SGPRs to VGPRs if we
diff --git a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
index b250310cfaa66..ab239e000b911 100644
--- a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
+++ b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
@@ -20,6 +20,7 @@
 #include "GCNSubtarget.h"
 #include "MCTargetDesc/AMDGPUMCTargetDesc.h"
 #include "SIMachineFunctionInfo.h"
+#include "SISpillUtils.h"
 #include "llvm/CodeGen/LiveIntervals.h"
 #include "llvm/CodeGen/MachineDominators.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
@@ -524,22 +525,7 @@ bool SILowerSGPRSpills::run(MachineFunction &MF) {
       FuncInfo->updateNonWWMRegMask(NonWwmRegMask);
     }
 
-    for (MachineBasicBlock &MBB : MF) {
-      // FIXME: The dead frame indices are replaced with a null register from
-      // the debug value instructions. We should instead, update it with the
-      // correct register value. But not sure the register value alone is
-      // adequate to lower the DIExpression. It should be worked out later.
-      for (MachineInstr &MI : MBB) {
-        if (MI.isDebugValue()) {
-          for (MachineOperand &Op : MI.debug_operands()) {
-            if (Op.isFI() && !MFI.isFixedObjectIndex(Op.getIndex()) &&
-                SpillFIs[Op.getIndex()]) {
-              Op.ChangeToRegister(Register(), false /*isDef*/);
-            }
-          }
-        }
-      }
-    }
+    clearDebugInfoForSpillFIs(MF, SpillFIs);
 
     // All those frame indices which are dead by now should be removed from the
     // function frame. Otherwise, there is a side effect such as re-mapping of
diff --git a/llvm/lib/Target/AMDGPU/SISpillUtils.cpp b/llvm/lib/Target/AMDGPU/SISpillUtils.cpp
new file mode 100644
index 0000000000000..3b118e9996f4f
--- /dev/null
+++ b/llvm/lib/Target/AMDGPU/SISpillUtils.cpp
@@ -0,0 +1,35 @@
+//===- SISpillUtils.cpp - SI spill helper functions -----------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "SISpillUtils.h"
+#include "llvm/ADT/BitVector.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/MachineFunction.h"
+
+using namespace llvm;
+
+void llvm::clearDebugInfoForSpillFIs(MachineFunction &MF,
+                                     const BitVector &SpillFIs) {
+  // FIXME: The dead frame indices are replaced with a null register from the
+  // debug value instructions. We should instead update it with the correct
+  // register value. But not sure the register value alone is adequate to lower
+  // the DIExpression. It should be worked out later.
+  MachineFrameInfo &MFI = MF.getFrameInfo();
+  for (MachineBasicBlock &MBB : MF) {
+    for (MachineInstr &MI : MBB) {
+      if (MI.isDebugValue()) {
+        for (MachineOperand &Op : MI.debug_operands()) {
+          if (Op.isFI() && !MFI.isFixedObjectIndex(Op.getIndex()) &&
+              SpillFIs[Op.getIndex()]) {
+            Op.ChangeToRegister(Register(), false /*isDef*/);
+          }
+        }
+      }
+    }
+  }
+}
diff --git a/llvm/lib/Target/AMDGPU/SISpillUtils.h b/llvm/lib/Target/AMDGPU/SISpillUtils.h
new file mode 100644
index 0000000000000..ed4c31204d1ff
--- /dev/null
+++ b/llvm/lib/Target/AMDGPU/SISpillUtils.h
@@ -0,0 +1,23 @@
+//===- SISpillUtils.h - SI spill helper functions ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_AMDGPU_SISPILLUTILS_H
+#define LLVM_LIB_TARGET_AMDGPU_SISPILLUTILS_H
+
+namespace llvm {
+
+class BitVector;
+class MachineFunction;
+
+/// Replace frame index operands with null registers in debug value instructions
+/// for the specified spill frame indices.
+void clearDebugInfoForSpillFIs(MachineFunction &MF, const BitVector &SpillFIs);
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_AMDGPU_SISPILLUTILS_H

>From c6626e5a0af3bc46c8e81fa1b6182ac96ecdf758 Mon Sep 17 00:00:00 2001
From: Sergio Afonso <Sergio.AfonsoFumero at amd.com>
Date: Thu, 26 Mar 2026 13:45:32 +0000
Subject: [PATCH 5/7] address comments

---
 llvm/lib/Target/AMDGPU/SISpillUtils.cpp | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/SISpillUtils.cpp b/llvm/lib/Target/AMDGPU/SISpillUtils.cpp
index 3b118e9996f4f..cad5930321481 100644
--- a/llvm/lib/Target/AMDGPU/SISpillUtils.cpp
+++ b/llvm/lib/Target/AMDGPU/SISpillUtils.cpp
@@ -22,12 +22,13 @@ void llvm::clearDebugInfoForSpillFIs(MachineFunction &MF,
   MachineFrameInfo &MFI = MF.getFrameInfo();
   for (MachineBasicBlock &MBB : MF) {
     for (MachineInstr &MI : MBB) {
-      if (MI.isDebugValue()) {
-        for (MachineOperand &Op : MI.debug_operands()) {
-          if (Op.isFI() && !MFI.isFixedObjectIndex(Op.getIndex()) &&
-              SpillFIs[Op.getIndex()]) {
-            Op.ChangeToRegister(Register(), false /*isDef*/);
-          }
+      if (!MI.isDebugValue())
+        continue;
+
+      for (MachineOperand &Op : MI.debug_operands()) {
+        if (Op.isFI() && !MFI.isFixedObjectIndex(Op.getIndex()) &&
+            SpillFIs[Op.getIndex()]) {
+          Op.ChangeToRegister(Register(), false /*isDef*/);
         }
       }
     }

>From 2ca8f64fb584acd94b280a53aa8740439deee2b7 Mon Sep 17 00:00:00 2001
From: Sergio Afonso <Sergio.AfonsoFumero at amd.com>
Date: Mon, 30 Mar 2026 11:49:30 +0100
Subject: [PATCH 6/7] avoid one loop over functions

---
 llvm/lib/Target/AMDGPU/SIFrameLowering.cpp   |  6 +++---
 llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp |  3 ++-
 llvm/lib/Target/AMDGPU/SISpillUtils.cpp      | 20 +++++++++-----------
 llvm/lib/Target/AMDGPU/SISpillUtils.h        |  6 ++++--
 4 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
index a329cec761ce1..ad6c2af73a575 100644
--- a/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
+++ b/llvm/lib/Target/AMDGPU/SIFrameLowering.cpp
@@ -1525,10 +1525,10 @@ void SIFrameLowering::processFunctionBeforeFrameFinalized(
         MBB.addLiveIn(Reg);
 
       MBB.sortUniqueLiveIns();
-    }
 
-    if (!SpillFIs.empty() && SeenDbgInstr)
-      clearDebugInfoForSpillFIs(MF, SpillFIs);
+      if (!SpillFIs.empty() && SeenDbgInstr)
+        clearDebugInfoForSpillFIs(MFI, MBB, SpillFIs);
+    }
   }
 
   // At this point we've already allocated all spilled SGPRs to VGPRs if we
diff --git a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
index ab239e000b911..b3b4c934816d1 100644
--- a/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
+++ b/llvm/lib/Target/AMDGPU/SILowerSGPRSpills.cpp
@@ -525,7 +525,8 @@ bool SILowerSGPRSpills::run(MachineFunction &MF) {
       FuncInfo->updateNonWWMRegMask(NonWwmRegMask);
     }
 
-    clearDebugInfoForSpillFIs(MF, SpillFIs);
+    for (MachineBasicBlock &MBB : MF)
+      clearDebugInfoForSpillFIs(MFI, MBB, SpillFIs);
 
     // All those frame indices which are dead by now should be removed from the
     // function frame. Otherwise, there is a side effect such as re-mapping of
diff --git a/llvm/lib/Target/AMDGPU/SISpillUtils.cpp b/llvm/lib/Target/AMDGPU/SISpillUtils.cpp
index cad5930321481..56788319d40d8 100644
--- a/llvm/lib/Target/AMDGPU/SISpillUtils.cpp
+++ b/llvm/lib/Target/AMDGPU/SISpillUtils.cpp
@@ -13,23 +13,21 @@
 
 using namespace llvm;
 
-void llvm::clearDebugInfoForSpillFIs(MachineFunction &MF,
+void llvm::clearDebugInfoForSpillFIs(MachineFrameInfo &MFI,
+                                     MachineBasicBlock &MBB,
                                      const BitVector &SpillFIs) {
   // FIXME: The dead frame indices are replaced with a null register from the
   // debug value instructions. We should instead update it with the correct
   // register value. But not sure the register value alone is adequate to lower
   // the DIExpression. It should be worked out later.
-  MachineFrameInfo &MFI = MF.getFrameInfo();
-  for (MachineBasicBlock &MBB : MF) {
-    for (MachineInstr &MI : MBB) {
-      if (!MI.isDebugValue())
-        continue;
+  for (MachineInstr &MI : MBB) {
+    if (!MI.isDebugValue())
+      continue;
 
-      for (MachineOperand &Op : MI.debug_operands()) {
-        if (Op.isFI() && !MFI.isFixedObjectIndex(Op.getIndex()) &&
-            SpillFIs[Op.getIndex()]) {
-          Op.ChangeToRegister(Register(), false /*isDef*/);
-        }
+    for (MachineOperand &Op : MI.debug_operands()) {
+      if (Op.isFI() && !MFI.isFixedObjectIndex(Op.getIndex()) &&
+          SpillFIs[Op.getIndex()]) {
+        Op.ChangeToRegister(Register(), false /*isDef*/);
       }
     }
   }
diff --git a/llvm/lib/Target/AMDGPU/SISpillUtils.h b/llvm/lib/Target/AMDGPU/SISpillUtils.h
index ed4c31204d1ff..aa2e88dc89829 100644
--- a/llvm/lib/Target/AMDGPU/SISpillUtils.h
+++ b/llvm/lib/Target/AMDGPU/SISpillUtils.h
@@ -12,11 +12,13 @@
 namespace llvm {
 
 class BitVector;
-class MachineFunction;
+class MachineBasicBlock;
+class MachineFrameInfo;
 
 /// Replace frame index operands with null registers in debug value instructions
 /// for the specified spill frame indices.
-void clearDebugInfoForSpillFIs(MachineFunction &MF, const BitVector &SpillFIs);
+void clearDebugInfoForSpillFIs(MachineFrameInfo &MFI, MachineBasicBlock &MBB,
+                               const BitVector &SpillFIs);
 
 } // end namespace llvm
 

>From ab006304d22445df751180417121086252365bf2 Mon Sep 17 00:00:00 2001
From: Sergio Afonso <Sergio.AfonsoFumero at amd.com>
Date: Tue, 31 Mar 2026 10:21:03 +0100
Subject: [PATCH 7/7] nit

---
 llvm/lib/Target/AMDGPU/SISpillUtils.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/Target/AMDGPU/SISpillUtils.cpp b/llvm/lib/Target/AMDGPU/SISpillUtils.cpp
index 56788319d40d8..b2d2e5a4cab64 100644
--- a/llvm/lib/Target/AMDGPU/SISpillUtils.cpp
+++ b/llvm/lib/Target/AMDGPU/SISpillUtils.cpp
@@ -27,7 +27,7 @@ void llvm::clearDebugInfoForSpillFIs(MachineFrameInfo &MFI,
     for (MachineOperand &Op : MI.debug_operands()) {
       if (Op.isFI() && !MFI.isFixedObjectIndex(Op.getIndex()) &&
           SpillFIs[Op.getIndex()]) {
-        Op.ChangeToRegister(Register(), false /*isDef*/);
+        Op.ChangeToRegister(Register(), /*isDef=*/false);
       }
     }
   }



More information about the llvm-commits mailing list