[llvm] [ISelDAG] Salvage debug info at isel by referring to frame indices. (PR #109126)
Bevin Hansson via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 18 05:02:57 PDT 2024
https://github.com/bevin-hansson created https://github.com/llvm/llvm-project/pull/109126
We can refer to frame index locations when salvaging debug info
for certain nodes, which prevents the compiler from optimizing
out the location.
>From bb902e2068fc795dd2d476d444d331534a66b460 Mon Sep 17 00:00:00 2001
From: Bevin Hansson <bevin.hansson at ericsson.com>
Date: Tue, 17 Sep 2024 15:53:49 +0200
Subject: [PATCH] [ISelDAG] Salvage debug info at isel by referring to frame
indices.
We can refer to frame index locations when salvaging debug info
for certain nodes, which prevents the compiler from optimizing
out the location.
---
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 16 +++-
llvm/test/CodeGen/SPARC/salvage-debug-isel.ll | 85 +++++++++++++++++++
llvm/test/CodeGen/X86/pr57673.ll | 4 +-
3 files changed, 100 insertions(+), 5 deletions(-)
create mode 100644 llvm/test/CodeGen/SPARC/salvage-debug-isel.ll
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 3918da3ef031b6..0b59a22b340bfc 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -11237,6 +11237,12 @@ void SelectionDAG::salvageDebugInfo(SDNode &N) {
if (!N.getHasDebugValue())
return;
+ auto handle = [](SDNode *Node, unsigned ResNo) {
+ if (auto *FISDN = dyn_cast<FrameIndexSDNode>(Node))
+ return SDDbgOperand::fromFrameIdx(FISDN->getIndex());
+ return SDDbgOperand::fromNode(Node, ResNo);
+ };
+
SmallVector<SDDbgValue *, 2> ClonedDVs;
for (auto *DV : GetDbgValues(&N)) {
if (DV->isInvalidated())
@@ -11272,7 +11278,7 @@ void SelectionDAG::salvageDebugInfo(SDNode &N) {
if (NewLocOps[i].getKind() != SDDbgOperand::SDNODE ||
NewLocOps[i].getSDNode() != &N)
continue;
- NewLocOps[i] = SDDbgOperand::fromNode(N0.getNode(), N0.getResNo());
+ NewLocOps[i] = handle(N0.getNode(), N0.getResNo());
if (RHSConstant) {
SmallVector<uint64_t, 3> ExprOps;
DIExpression::appendOffset(ExprOps, Offset);
@@ -11327,7 +11333,7 @@ void SelectionDAG::salvageDebugInfo(SDNode &N) {
NewLocOps[i].getSDNode() != &N)
continue;
- NewLocOps[i] = SDDbgOperand::fromNode(N0.getNode(), N0.getResNo());
+ NewLocOps[i] = handle(N0.getNode(), N0.getResNo());
DbgExpression = DIExpression::appendOpsToArg(DbgExpression, ExtOps, i);
Changed = true;
}
@@ -11350,7 +11356,11 @@ void SelectionDAG::salvageDebugInfo(SDNode &N) {
}
for (SDDbgValue *Dbg : ClonedDVs) {
- assert(!Dbg->getSDNodes().empty() &&
+ assert((!Dbg->getSDNodes().empty() ||
+ llvm::any_of(Dbg->getLocationOps(),
+ [&](const SDDbgOperand &Op) {
+ return Op.getKind() == SDDbgOperand::FRAMEIX;
+ })) &&
"Salvaged DbgValue should depend on a new SDNode");
AddDbgValue(Dbg, false);
}
diff --git a/llvm/test/CodeGen/SPARC/salvage-debug-isel.ll b/llvm/test/CodeGen/SPARC/salvage-debug-isel.ll
new file mode 100644
index 00000000000000..af0a6ba25f97ca
--- /dev/null
+++ b/llvm/test/CodeGen/SPARC/salvage-debug-isel.ll
@@ -0,0 +1,85 @@
+; RUN: llc -march=sparc -O1 %s -o - | FileCheck %s
+
+; Debug info salvaging in isel means we should see a location for this variable.
+
+; CHECK-LABEL: a:
+; CHECK: !DEBUG_VALUE: a:d <- [DW_OP_plus_uconst 98, DW_OP_plus_uconst 3, DW_OP_stack_value] $o6
+
+define dso_local zeroext i16 @a() local_unnamed_addr #0 !dbg !7 {
+entry:
+ %b = alloca [6 x i8], align 1, !DIAssignID !24
+ #dbg_assign(i1 undef, !14, !DIExpression(), !24, ptr %b, !DIExpression(), !25)
+ call void @llvm.lifetime.start.p0(i64 6, ptr nonnull %b) #2, !dbg !26
+ %arrayidx = getelementptr inbounds [6 x i8], ptr %b, i32 0, i32 undef, !dbg !27
+ store i8 4, ptr %arrayidx, align 1, !dbg !28, !tbaa !29
+ %arrayidx1 = getelementptr inbounds i8, ptr %b, i32 3, !dbg !32
+ #dbg_value(ptr %arrayidx1, !22, !DIExpression(), !25)
+ %0 = load i8, ptr %arrayidx1, align 1, !dbg !33, !tbaa !29
+ %tobool.not = icmp eq i8 %0, 0, !dbg !35
+ br i1 %tobool.not, label %if.end, label %for.cond, !dbg !36
+
+for.cond: ; preds = %entry, %for.cond
+ br label %for.cond, !dbg !37, !llvm.loop !40
+
+if.end: ; preds = %entry
+ call void @llvm.lifetime.end.p0(i64 6, ptr nonnull %b) #2, !dbg !44
+ ret i16 undef, !dbg !44
+}
+
+declare void @llvm.lifetime.start.p0(i64 immarg, ptr nocapture) #1
+
+declare void @llvm.lifetime.end.p0(i64 immarg, ptr nocapture) #1
+
+attributes #0 = { nofree noinline norecurse nosync nounwind memory(none) "no-builtins" "no-trapping-math"="true" "stack-protector-buffer-size"="8" }
+attributes #1 = { mustprogress nocallback nofree nosync nounwind willreturn memory(argmem: readwrite) }
+attributes #2 = { nounwind }
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3, !4, !5}
+!llvm.ident = !{!6}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C11, file: !1, producer: "clang version 20.0.0git.prerel", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+!1 = !DIFile(filename: "file.c", directory: "/path", checksumkind: CSK_MD5, checksum: "aa7b5139660a2329a6409414c44cc1f6")
+!2 = !{i32 7, !"Dwarf Version", i32 5}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !{i32 1, !"wchar_size", i32 4}
+!5 = !{i32 7, !"debug-info-assignment-tracking", i1 true}
+!6 = !{!"clang version 20.0.0git.prerel"}
+!7 = distinct !DISubprogram(name: "a", scope: !1, file: !1, line: 2, type: !8, scopeLine: 2, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !13)
+!8 = !DISubroutineType(types: !9)
+!9 = !{!10}
+!10 = !DIDerivedType(tag: DW_TAG_typedef, name: "uint16_t", file: !11, line: 277, baseType: !12)
+!11 = !DIFile(filename: "stdint.h", directory: "", checksumkind: CSK_MD5, checksum: "d9e8f73f3756bbd642f1729623e09484")
+!12 = !DIBasicType(name: "unsigned short", size: 16, encoding: DW_ATE_unsigned)
+!13 = !{!14, !20, !22}
+!14 = !DILocalVariable(name: "b", scope: !7, file: !1, line: 3, type: !15)
+!15 = !DICompositeType(tag: DW_TAG_array_type, baseType: !16, size: 48, elements: !18)
+!16 = !DIDerivedType(tag: DW_TAG_typedef, name: "int8_t", file: !11, line: 298, baseType: !17)
+!17 = !DIBasicType(name: "signed char", size: 8, encoding: DW_ATE_signed_char)
+!18 = !{!19}
+!19 = !DISubrange(count: 6)
+!20 = !DILocalVariable(name: "c", scope: !7, file: !1, line: 4, type: !21)
+!21 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!22 = !DILocalVariable(name: "d", scope: !7, file: !1, line: 6, type: !23)
+!23 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !16, size: 32)
+!24 = distinct !DIAssignID()
+!25 = !DILocation(line: 0, scope: !7)
+!26 = !DILocation(line: 3, column: 3, scope: !7)
+!27 = !DILocation(line: 5, column: 3, scope: !7)
+!28 = !DILocation(line: 5, column: 8, scope: !7)
+!29 = !{!30, !30, i64 0}
+!30 = !{!"omnipotent char", !31, i64 0}
+!31 = !{!"Simple C/C++ TBAA"}
+!32 = !DILocation(line: 6, column: 16, scope: !7)
+!33 = !DILocation(line: 7, column: 33, scope: !34)
+!34 = distinct !DILexicalBlock(scope: !7, file: !1, line: 7, column: 7)
+!35 = !DILocation(line: 7, column: 7, scope: !34)
+!36 = !DILocation(line: 7, column: 7, scope: !7)
+!37 = !DILocation(line: 8, column: 5, scope: !38)
+!38 = distinct !DILexicalBlock(scope: !39, file: !1, line: 8, column: 5)
+!39 = distinct !DILexicalBlock(scope: !34, file: !1, line: 8, column: 5)
+!40 = distinct !{!40, !41, !42, !43}
+!41 = !DILocation(line: 8, column: 5, scope: !39)
+!42 = !DILocation(line: 9, column: 7, scope: !39)
+!43 = !{!"llvm.loop.unroll.disable"}
+!44 = !DILocation(line: 10, column: 1, scope: !7)
diff --git a/llvm/test/CodeGen/X86/pr57673.ll b/llvm/test/CodeGen/X86/pr57673.ll
index cf7717f420480b..4ca8ae91f9e6fc 100644
--- a/llvm/test/CodeGen/X86/pr57673.ll
+++ b/llvm/test/CodeGen/X86/pr57673.ll
@@ -37,7 +37,7 @@ define void @foo() {
; NORMAL-NEXT: {{ $}}
; NORMAL-NEXT: [[MOVUPSrm:%[0-9]+]]:vr128 = MOVUPSrm %stack.1.i, 1, $noreg, 40, $noreg :: (load (s128) from %ir.i4, align 8)
; NORMAL-NEXT: MOVUPSmr $noreg, 1, $noreg, 0, $noreg, killed [[MOVUPSrm]] :: (store (s128) into `ptr null`, align 8)
- ; NORMAL-NEXT: DBG_VALUE $noreg, $noreg, !3, !DIExpression(), debug-location !8
+ ; NORMAL-NEXT: DBG_VALUE_LIST !3, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_plus_uconst, 40, DW_OP_stack_value), %stack.1.i, %stack.1.i, debug-location !8
; NORMAL-NEXT: [[MOVUPSrm1:%[0-9]+]]:vr128 = MOVUPSrm %stack.1.i, 1, $noreg, 40, $noreg :: (load (s128) from %ir.i6, align 8)
; NORMAL-NEXT: MOVUPSmr $noreg, 1, $noreg, 0, $noreg, killed [[MOVUPSrm1]] :: (store (s128) into `ptr null`, align 8)
; NORMAL-NEXT: {{ $}}
@@ -76,7 +76,7 @@ define void @foo() {
; INSTRREF-NEXT: {{ $}}
; INSTRREF-NEXT: [[MOVUPSrm:%[0-9]+]]:vr128 = MOVUPSrm %stack.1.i, 1, $noreg, 40, $noreg :: (load (s128) from %ir.i4, align 8)
; INSTRREF-NEXT: MOVUPSmr $noreg, 1, $noreg, 0, $noreg, killed [[MOVUPSrm]] :: (store (s128) into `ptr null`, align 8)
- ; INSTRREF-NEXT: DBG_VALUE $noreg, $noreg, !3, !DIExpression(), debug-location !8
+ ; INSTRREF-NEXT: DBG_VALUE_LIST !3, !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_plus_uconst, 40, DW_OP_stack_value), %stack.1.i, %stack.1.i, debug-location !8
; INSTRREF-NEXT: [[MOVUPSrm1:%[0-9]+]]:vr128 = MOVUPSrm %stack.1.i, 1, $noreg, 40, $noreg :: (load (s128) from %ir.i6, align 8)
; INSTRREF-NEXT: MOVUPSmr $noreg, 1, $noreg, 0, $noreg, killed [[MOVUPSrm1]] :: (store (s128) into `ptr null`, align 8)
; INSTRREF-NEXT: {{ $}}
More information about the llvm-commits
mailing list