[llvm] [FastISel] Ignore debug uses when folding a load (PR #228719)
Aochang Liu via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 3 08:53:49 PDT 2026
https://github.com/HelloWorldU updated https://github.com/llvm/llvm-project/pull/228719
>From d1e636e7c84cf684b4609cc6ccd3978d335fc7da Mon Sep 17 00:00:00 2001
From: HelloWorldU <asd001liu at gmail.com>
Date: Sat, 3 Oct 2026 22:50:13 +0800
Subject: [PATCH 1/2] [FastISel] Ignore debug uses when folding a load
tryToFoldLoad counted DBG_VALUE as a use of the loaded vreg, so the load was
folded only without -g. Check for a single non-debug use, and mark debug
values of the vreg undef once the load is folded, as PeepholeOptimizer does.
Fixes #228711
Assisted-by: Claude Opus 5.5
---
llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 17 ++++++----
.../CodeGen/X86/fast-isel-fold-load-dbg.ll | 33 +++++++++++++++++++
2 files changed, 44 insertions(+), 6 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/fast-isel-fold-load-dbg.ll
diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp
index 4f391390705081..3dd81d54773b41 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 00000000000000..a154c045b93f2e
--- /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)
>From d33df4043b715f647a9014717ec208fc688dd4b3 Mon Sep 17 00:00:00 2001
From: HelloWorldU <asd001liu at gmail.com>
Date: Sat, 3 Oct 2026 23:53:22 +0800
Subject: [PATCH 2/2] Update LTO_CCU_zero_loc_cov.ll
The inlined parameter "a" in the optnone main is described by a loaded value
that is now folded, so its DBG_VALUE becomes undef and it loses its location.
Assisted-by: Claude Opus 5.5
---
llvm/test/tools/llvm-dwarfdump/X86/LTO_CCU_zero_loc_cov.ll | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/llvm/test/tools/llvm-dwarfdump/X86/LTO_CCU_zero_loc_cov.ll b/llvm/test/tools/llvm-dwarfdump/X86/LTO_CCU_zero_loc_cov.ll
index fa32b35658047a..27ac88398dae35 100644
--- a/llvm/test/tools/llvm-dwarfdump/X86/LTO_CCU_zero_loc_cov.ll
+++ b/llvm/test/tools/llvm-dwarfdump/X86/LTO_CCU_zero_loc_cov.ll
@@ -28,9 +28,9 @@
;; return result;
;;}
-; CHECK: "#source variables with location": 10,
-; CHECK: "#variables with 0% of parent scope covered by DW_AT_location": 1,
-; CHECK: "#params with 0% of parent scope covered by DW_AT_location": 1,
+; CHECK: "#source variables with location": 9,
+; CHECK: "#variables with 0% of parent scope covered by DW_AT_location": 2,
+; CHECK: "#params with 0% of parent scope covered by DW_AT_location": 2,
; ModuleID = 'linked.ll'
source_filename = "llvm-link"
More information about the llvm-commits
mailing list