[llvm] [FastISel] Ignore debug uses when folding a load (PR #228719)

via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 3 07:55:28 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-backend-x86

Author: Aochang Liu (HelloWorldU)

<details>
<summary>Changes</summary>

DBG_VALUE was counted as a use of the loaded value, so the load was folded only without -g. Once the load is folded, its vreg is never defined, so mark its debug values undef.

Fixes #<!-- -->228711

Assisted-by: Claude Opus 5.5

---
Full diff: https://github.com/llvm/llvm-project/pull/228719.diff


2 Files Affected:

- (modified) llvm/lib/CodeGen/SelectionDAG/FastISel.cpp (+11-6) 
- (added) llvm/test/CodeGen/X86/fast-isel-fold-load-dbg.ll (+33) 


``````````diff
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index 4f39139070508..3dd81d54773b4 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
@@ -2240,10 +2240,10 @@ bool FastISel::tryToFoldLoad(const LoadInst *LI, const Instruction *FoldInst) {
   if (!LoadReg)
     return false;
 
-  // We can't fold if this vreg has no uses or more than one use.  Multiple uses
-  // may mean that the instruction got lowered to multiple MIs, or the use of
-  // the loaded value ended up being multiple operands of the result.
-  if (!MRI.hasOneUse(LoadReg))
+  // We can't fold if this vreg has no uses or more than one non-debug use.
+  // Multiple uses may mean that the instruction got lowered to multiple MIs, or
+  // the use of the loaded value ended up being multiple operands of the result.
+  if (!MRI.hasOneNonDBGUse(LoadReg))
     return false;
 
   // If the register has fixups, there may be additional uses through a
@@ -2251,7 +2251,7 @@ bool FastISel::tryToFoldLoad(const LoadInst *LI, const Instruction *FoldInst) {
   if (FuncInfo.RegsWithFixups.contains(LoadReg))
     return false;
 
-  MachineRegisterInfo::reg_iterator RI = MRI.reg_begin(LoadReg);
+  MachineRegisterInfo::use_nodbg_iterator RI = MRI.use_nodbg_begin(LoadReg);
   MachineInstr *User = RI->getParent();
 
   // Set the insertion point properly.  Folding the load can cause generation of
@@ -2261,7 +2261,12 @@ bool FastISel::tryToFoldLoad(const LoadInst *LI, const Instruction *FoldInst) {
   FuncInfo.MBB = User->getParent();
 
   // Ask the target to try folding the load.
-  return tryToFoldLoadIntoMI(User, RI.getOperandNo(), LI);
+  if (!tryToFoldLoadIntoMI(User, RI.getOperandNo(), LI))
+    return false;
+
+  // The loaded value no longer lives in LoadReg.
+  MRI.markUsesInDebugValueAsUndef(LoadReg);
+  return true;
 }
 
 bool FastISel::canFoldAddIntoGEP(const User *GEP, const Value *Add) {
diff --git a/llvm/test/CodeGen/X86/fast-isel-fold-load-dbg.ll b/llvm/test/CodeGen/X86/fast-isel-fold-load-dbg.ll
new file mode 100644
index 0000000000000..a154c045b93f2
--- /dev/null
+++ b/llvm/test/CodeGen/X86/fast-isel-fold-load-dbg.ll
@@ -0,0 +1,33 @@
+; RUN: llc -O0 -mtriple=x86_64-unknown-unknown -stop-after=finalize-isel %s -o - | \
+; RUN:    FileCheck %s --check-prefixes=CHECK,O0
+; RUN: llc -fast-isel -fast-isel-abort=1 -mtriple=x86_64-unknown-unknown -stop-after=finalize-isel %s -o - | \
+; RUN:    FileCheck %s --check-prefixes=CHECK,IREF
+
+; A debug use of the loaded value must not prevent folding the load, and the
+; debug value must not refer to the now undefined vreg. At -O0 this is a
+; DBG_VALUE; with instruction referencing it is a DBG_INSTR_REF that becomes an
+; undef DBG_VALUE_LIST.
+
+; CHECK-LABEL: name: fold_load_dbg
+; CHECK-NOT:   MOV64rm
+; O0:          DBG_VALUE $noreg, $noreg,
+; IREF:        DBG_VALUE_LIST {{.*}}, $noreg,
+; CHECK-NEXT:  ADD64rm
+define i64 @fold_load_dbg(ptr %a, i64 %b) !dbg !4 {
+  %1 = load i64, ptr %a, align 8
+    #dbg_value(i64 %1, !6, !DIExpression(), !7)
+  %2 = add i64 %1, %b
+  ret i64 %2
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, emissionKind: FullDebug)
+!1 = !DIFile(filename: "t.c", directory: "/")
+!2 = !{i32 2, !"Debug Info Version", i32 3}
+!3 = !DISubroutineType(types: !{})
+!4 = distinct !DISubprogram(name: "fold_load_dbg", scope: !1, file: !1, type: !3, spFlags: DISPFlagDefinition, unit: !0)
+!5 = !DIBasicType(name: "long", size: 64, encoding: DW_ATE_signed)
+!6 = !DILocalVariable(name: "x", scope: !4, file: !1, type: !5)
+!7 = !DILocation(line: 1, scope: !4)

``````````

</details>


https://github.com/llvm/llvm-project/pull/228719


More information about the llvm-commits mailing list