[llvm] [DebugInfo][JumpThreading] Fix missing debug location updates (PR #91581)
Shan Huang via llvm-commits
llvm-commits at lists.llvm.org
Thu May 9 06:49:17 PDT 2024
https://github.com/Apochens updated https://github.com/llvm/llvm-project/pull/91581
>From ffd78837d12effbd73b4450d78f85d6253f020fe Mon Sep 17 00:00:00 2001
From: Apochens <52285902006 at stu.ecnu.edu.cn>
Date: Thu, 9 May 2024 10:14:23 +0000
Subject: [PATCH 1/4] fix missing debugloc updates
---
llvm/lib/Transforms/Scalar/JumpThreading.cpp | 7 +-
.../JumpThreading/guard-split-debuginfo.ll | 6 +-
.../preserving-debugloc-fold-select.ll | 98 +++++++++++++++++++
3 files changed, 109 insertions(+), 2 deletions(-)
create mode 100644 llvm/test/Transforms/JumpThreading/preserving-debugloc-fold-select.ll
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index 08d82fa66da30..f7778166bc4fb 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -1278,9 +1278,12 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
// only happen in dead loops.
if (AvailableVal == LoadI)
AvailableVal = PoisonValue::get(LoadI->getType());
- if (AvailableVal->getType() != LoadI->getType())
+ if (AvailableVal->getType() != LoadI->getType()) {
AvailableVal = CastInst::CreateBitOrPointerCast(
AvailableVal, LoadI->getType(), "", LoadI->getIterator());
+ if (Instruction * CI = dyn_cast<Instruction>(AvailableVal))
+ CI->setDebugLoc(LoadI->getDebugLoc());
+ }
LoadI->replaceAllUsesWith(AvailableVal);
LoadI->eraseFromParent();
return true;
@@ -2983,6 +2986,7 @@ bool JumpThreadingPass::tryToUnfoldSelectInCurrBB(BasicBlock *BB) {
PHINode *NewPN = PHINode::Create(SI->getType(), 2, "", SI->getIterator());
NewPN->addIncoming(SI->getTrueValue(), Term->getParent());
NewPN->addIncoming(SI->getFalseValue(), BB);
+ NewBB->setDebugLoc(SI->getDebugLoc());
SI->replaceAllUsesWith(NewPN);
SI->eraseFromParent();
// NewBB and SplitBB are newly created blocks which require insertion.
@@ -3120,6 +3124,7 @@ bool JumpThreadingPass::threadGuard(BasicBlock *BB, IntrinsicInst *Guard,
PHINode *NewPN = PHINode::Create(Inst->getType(), 2);
NewPN->addIncoming(UnguardedMapping[Inst], UnguardedBlock);
NewPN->addIncoming(GuardedMapping[Inst], GuardedBlock);
+ NewPN->setDebugLoc(Inst->getDebugLoc());
NewPN->insertBefore(InsertionPoint);
Inst->replaceAllUsesWith(NewPN);
}
diff --git a/llvm/test/Transforms/JumpThreading/guard-split-debuginfo.ll b/llvm/test/Transforms/JumpThreading/guard-split-debuginfo.ll
index 05ff74939449c..203a8a9ae2395 100644
--- a/llvm/test/Transforms/JumpThreading/guard-split-debuginfo.ll
+++ b/llvm/test/Transforms/JumpThreading/guard-split-debuginfo.ll
@@ -7,6 +7,9 @@
; parent blocks. And that ino jump-threading, the old dbg.value gets
; deleted.
+; Test debug location preserving in function threadGuard, which replaces
+; instructions with PHINodes at the end of the function. [[TMP1]]
+
declare void @llvm.experimental.guard(i1, ...)
declare i32 @f1()
@@ -33,8 +36,9 @@ define i32 @branch_implies_guard(i32 %a) !dbg !7 {
; CHECK-NEXT: br label [[MERGE]]
; CHECK: Merge:
; CHECK-NEXT: [[RETPHI:%.*]] = phi i32 [ [[V1]], [[T1_SPLIT]] ], [ [[V2]], [[F1_SPLIT]] ]
-; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[RETVAL3]], [[T1_SPLIT]] ], [ [[RETVAL1]], [[F1_SPLIT]] ]
+; CHECK-NEXT: [[TMP1:%.*]] = phi i32 [ [[RETVAL3]], [[T1_SPLIT]] ], [ [[RETVAL1]], [[F1_SPLIT]] ], !dbg [[DBG12]]
; CHECK-NEXT: ret i32 [[TMP1]], !dbg [[DBG12]]
+; CHECK: [[DBG12]] = !DILocation(line: 13,
;
%cond = icmp slt i32 %a, 10
br i1 %cond, label %T1, label %F1, !dbg !26
diff --git a/llvm/test/Transforms/JumpThreading/preserving-debugloc-fold-select.ll b/llvm/test/Transforms/JumpThreading/preserving-debugloc-fold-select.ll
new file mode 100644
index 0000000000000..36137c23b42a5
--- /dev/null
+++ b/llvm/test/Transforms/JumpThreading/preserving-debugloc-fold-select.ll
@@ -0,0 +1,98 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt < %s -S -passes=jump-threading | FileCheck %s
+
+; Test the debug location update of the newly created PHINode
+; which replaces the select instruction in .exit block.
+
+define i32 @unfold3(i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z, i32 %j) !dbg !5 {
+; CHECK-LABEL: define i32 @unfold3(
+; CHECK-SAME: i32 [[U:%.*]], i32 [[V:%.*]], i32 [[W:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]], i32 [[J:%.*]]) !dbg [[DBG5:![0-9]+]] {
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[J]], 2, !dbg [[DBG19:![0-9]+]]
+; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[U]], [[V]], !dbg [[DBG20:![0-9]+]]
+; CHECK-NEXT: br i1 [[CMP_I]], label [[DOTEXIT_THREAD4:%.*]], label [[COND_FALSE_I:%.*]], !dbg [[DBG21:![0-9]+]]
+; CHECK: cond.false.i:
+; CHECK-NEXT: [[CMP4_I:%.*]] = icmp sgt i32 [[U]], [[V]], !dbg [[DBG22:![0-9]+]]
+; CHECK-NEXT: br i1 [[CMP4_I]], label [[DOTEXIT_THREAD:%.*]], label [[COND_FALSE_6_I:%.*]], !dbg [[DBG23:![0-9]+]]
+; CHECK: cond.false.6.i:
+; CHECK-NEXT: [[CMP8_I:%.*]] = icmp slt i32 [[W]], [[X]], !dbg [[DBG24:![0-9]+]]
+; CHECK-NEXT: br i1 [[CMP8_I]], label [[DOTEXIT_THREAD4]], label [[COND_FALSE_10_I:%.*]], !dbg [[DBG25:![0-9]+]]
+; CHECK: cond.false.10.i:
+; CHECK-NEXT: [[CMP13_I:%.*]] = icmp sgt i32 [[W]], [[X]], !dbg [[DBG26:![0-9]+]]
+; CHECK-NEXT: br i1 [[CMP13_I]], label [[DOTEXIT_THREAD]], label [[DOTEXIT:%.*]], !dbg [[DBG27:![0-9]+]]
+; CHECK: .exit:
+; CHECK-NEXT: [[PHITMP:%.*]] = icmp sge i32 [[Y]], [[Z]], !dbg [[DBG28:![0-9]+]]
+; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[PHITMP]]
+; CHECK-NEXT: br i1 [[COND_FR]], label [[DOTEXIT_THREAD]], label [[DOTEXIT_THREAD4]], !dbg [[DBG29:![0-9]+]]
+; CHECK: .exit.thread:
+; CHECK-NEXT: br label [[DOTEXIT_THREAD4]], !dbg [[DBG29]]
+; CHECK: .exit.thread4:
+; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ [[J]], [[DOTEXIT_THREAD]] ], [ [[ADD3]], [[DOTEXIT]] ], [ [[ADD3]], [[ENTRY:%.*]] ], [ [[ADD3]], [[COND_FALSE_6_I]] ], !dbg [[DBG29]]
+; CHECK-NEXT: ret i32 [[TMP0]], !dbg [[DBG30:![0-9]+]]
+;
+; CHECK: [[DBG29]] = !DILocation(line: 13,
+;
+entry:
+ %add3 = add nsw i32 %j, 2, !dbg !19
+ %cmp.i = icmp slt i32 %u, %v, !dbg !20
+ br i1 %cmp.i, label %.exit, label %cond.false.i, !dbg !21
+
+cond.false.i: ; preds = %entry
+ %cmp4.i = icmp sgt i32 %u, %v, !dbg !22
+ br i1 %cmp4.i, label %.exit, label %cond.false.6.i, !dbg !23
+
+cond.false.6.i: ; preds = %cond.false.i
+ %cmp8.i = icmp slt i32 %w, %x, !dbg !24
+ br i1 %cmp8.i, label %.exit, label %cond.false.10.i, !dbg !25
+
+cond.false.10.i: ; preds = %cond.false.6.i
+ %cmp13.i = icmp sgt i32 %w, %x, !dbg !26
+ br i1 %cmp13.i, label %.exit, label %cond.false.15.i, !dbg !27
+
+cond.false.15.i: ; preds = %cond.false.10.i
+ %phitmp = icmp sge i32 %y, %z, !dbg !28
+ br label %.exit, !dbg !29
+
+.exit: ; preds = %cond.false.15.i, %cond.false.10.i, %cond.false.6.i, %cond.false.i, %entry
+ %cond23.i = phi i1 [ false, %entry ], [ true, %cond.false.i ], [ false, %cond.false.6.i ], [ %phitmp, %cond.false.15.i ], [ true, %cond.false.10.i ], !dbg !30
+ %j.add3 = select i1 %cond23.i, i32 %j, i32 %add3, !dbg !31
+ ret i32 %j.add3, !dbg !32
+}
+
+!llvm.dbg.cu = !{!0}
+!llvm.debugify = !{!2, !3}
+!llvm.module.flags = !{!4}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: "debugify", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)
+!1 = !DIFile(filename: "preserving-debugloc-trytofoldselect.ll", directory: "/")
+!2 = !{i32 14}
+!3 = !{i32 8}
+!4 = !{i32 2, !"Debug Info Version", i32 3}
+!5 = distinct !DISubprogram(name: "unfold3", linkageName: "unfold3", scope: null, file: !1, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !8)
+!6 = !DISubroutineType(types: !7)
+!7 = !{}
+!8 = !{!9, !11, !13, !14, !15, !16, !17, !18}
+!9 = !DILocalVariable(name: "1", scope: !5, file: !1, line: 1, type: !10)
+!10 = !DIBasicType(name: "ty32", size: 32, encoding: DW_ATE_unsigned)
+!11 = !DILocalVariable(name: "2", scope: !5, file: !1, line: 2, type: !12)
+!12 = !DIBasicType(name: "ty8", size: 8, encoding: DW_ATE_unsigned)
+!13 = !DILocalVariable(name: "3", scope: !5, file: !1, line: 4, type: !12)
+!14 = !DILocalVariable(name: "4", scope: !5, file: !1, line: 6, type: !12)
+!15 = !DILocalVariable(name: "5", scope: !5, file: !1, line: 8, type: !12)
+!16 = !DILocalVariable(name: "6", scope: !5, file: !1, line: 10, type: !12)
+!17 = !DILocalVariable(name: "7", scope: !5, file: !1, line: 12, type: !12)
+!18 = !DILocalVariable(name: "8", scope: !5, file: !1, line: 13, type: !10)
+!19 = !DILocation(line: 1, column: 1, scope: !5)
+!20 = !DILocation(line: 2, column: 1, scope: !5)
+!21 = !DILocation(line: 3, column: 1, scope: !5)
+!22 = !DILocation(line: 4, column: 1, scope: !5)
+!23 = !DILocation(line: 5, column: 1, scope: !5)
+!24 = !DILocation(line: 6, column: 1, scope: !5)
+!25 = !DILocation(line: 7, column: 1, scope: !5)
+!26 = !DILocation(line: 8, column: 1, scope: !5)
+!27 = !DILocation(line: 9, column: 1, scope: !5)
+!28 = !DILocation(line: 10, column: 1, scope: !5)
+!29 = !DILocation(line: 11, column: 1, scope: !5)
+!30 = !DILocation(line: 12, column: 1, scope: !5)
+!31 = !DILocation(line: 13, column: 1, scope: !5)
+!32 = !DILocation(line: 14, column: 1, scope: !5)
>From bd1478a0c069ce74f7466e6d2992fd6b6d9b43b3 Mon Sep 17 00:00:00 2001
From: Apochens <52285902006 at stu.ecnu.edu.cn>
Date: Thu, 9 May 2024 11:22:53 +0000
Subject: [PATCH 2/4] correct the variable name
---
llvm/lib/Transforms/Scalar/JumpThreading.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index f7778166bc4fb..829822b01f636 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -1281,7 +1281,7 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
if (AvailableVal->getType() != LoadI->getType()) {
AvailableVal = CastInst::CreateBitOrPointerCast(
AvailableVal, LoadI->getType(), "", LoadI->getIterator());
- if (Instruction * CI = dyn_cast<Instruction>(AvailableVal))
+ if (Instruction *CI = dyn_cast<Instruction>(AvailableVal))
CI->setDebugLoc(LoadI->getDebugLoc());
}
LoadI->replaceAllUsesWith(AvailableVal);
@@ -2986,7 +2986,7 @@ bool JumpThreadingPass::tryToUnfoldSelectInCurrBB(BasicBlock *BB) {
PHINode *NewPN = PHINode::Create(SI->getType(), 2, "", SI->getIterator());
NewPN->addIncoming(SI->getTrueValue(), Term->getParent());
NewPN->addIncoming(SI->getFalseValue(), BB);
- NewBB->setDebugLoc(SI->getDebugLoc());
+ NewPN->setDebugLoc(SI->getDebugLoc());
SI->replaceAllUsesWith(NewPN);
SI->eraseFromParent();
// NewBB and SplitBB are newly created blocks which require insertion.
>From 353762b6d8683af7c18bbc9586e664b54d6714e6 Mon Sep 17 00:00:00 2001
From: Apochens <52285902006 at stu.ecnu.edu.cn>
Date: Thu, 9 May 2024 13:44:11 +0000
Subject: [PATCH 3/4] refine
---
llvm/lib/Transforms/Scalar/JumpThreading.cpp | 3 +--
.../JumpThreading/guard-split-debuginfo.ll | 4 ++--
.../preserving-debugloc-fold-select.ll | 23 +------------------
3 files changed, 4 insertions(+), 26 deletions(-)
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index 829822b01f636..31ac33217fe53 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -1281,8 +1281,7 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
if (AvailableVal->getType() != LoadI->getType()) {
AvailableVal = CastInst::CreateBitOrPointerCast(
AvailableVal, LoadI->getType(), "", LoadI->getIterator());
- if (Instruction *CI = dyn_cast<Instruction>(AvailableVal))
- CI->setDebugLoc(LoadI->getDebugLoc());
+ cast<Instruction>(AvailableVal)->setDebugLoc(LoadI->getDebugLoc());
}
LoadI->replaceAllUsesWith(AvailableVal);
LoadI->eraseFromParent();
diff --git a/llvm/test/Transforms/JumpThreading/guard-split-debuginfo.ll b/llvm/test/Transforms/JumpThreading/guard-split-debuginfo.ll
index 203a8a9ae2395..f94ae80f30058 100644
--- a/llvm/test/Transforms/JumpThreading/guard-split-debuginfo.ll
+++ b/llvm/test/Transforms/JumpThreading/guard-split-debuginfo.ll
@@ -7,8 +7,8 @@
; parent blocks. And that ino jump-threading, the old dbg.value gets
; deleted.
-; Test debug location preserving in function threadGuard, which replaces
-; instructions with PHINodes at the end of the function. [[TMP1]]
+; Test that JumpThreading's threadGuard() propagates the debug location
+; to the `phi` from the instruction it replaces (`%retval`)
declare void @llvm.experimental.guard(i1, ...)
diff --git a/llvm/test/Transforms/JumpThreading/preserving-debugloc-fold-select.ll b/llvm/test/Transforms/JumpThreading/preserving-debugloc-fold-select.ll
index 36137c23b42a5..a4cf49077b6d2 100644
--- a/llvm/test/Transforms/JumpThreading/preserving-debugloc-fold-select.ll
+++ b/llvm/test/Transforms/JumpThreading/preserving-debugloc-fold-select.ll
@@ -5,29 +5,8 @@
; which replaces the select instruction in .exit block.
define i32 @unfold3(i32 %u, i32 %v, i32 %w, i32 %x, i32 %y, i32 %z, i32 %j) !dbg !5 {
-; CHECK-LABEL: define i32 @unfold3(
-; CHECK-SAME: i32 [[U:%.*]], i32 [[V:%.*]], i32 [[W:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]], i32 [[J:%.*]]) !dbg [[DBG5:![0-9]+]] {
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[ADD3:%.*]] = add nsw i32 [[J]], 2, !dbg [[DBG19:![0-9]+]]
-; CHECK-NEXT: [[CMP_I:%.*]] = icmp slt i32 [[U]], [[V]], !dbg [[DBG20:![0-9]+]]
-; CHECK-NEXT: br i1 [[CMP_I]], label [[DOTEXIT_THREAD4:%.*]], label [[COND_FALSE_I:%.*]], !dbg [[DBG21:![0-9]+]]
-; CHECK: cond.false.i:
-; CHECK-NEXT: [[CMP4_I:%.*]] = icmp sgt i32 [[U]], [[V]], !dbg [[DBG22:![0-9]+]]
-; CHECK-NEXT: br i1 [[CMP4_I]], label [[DOTEXIT_THREAD:%.*]], label [[COND_FALSE_6_I:%.*]], !dbg [[DBG23:![0-9]+]]
-; CHECK: cond.false.6.i:
-; CHECK-NEXT: [[CMP8_I:%.*]] = icmp slt i32 [[W]], [[X]], !dbg [[DBG24:![0-9]+]]
-; CHECK-NEXT: br i1 [[CMP8_I]], label [[DOTEXIT_THREAD4]], label [[COND_FALSE_10_I:%.*]], !dbg [[DBG25:![0-9]+]]
-; CHECK: cond.false.10.i:
-; CHECK-NEXT: [[CMP13_I:%.*]] = icmp sgt i32 [[W]], [[X]], !dbg [[DBG26:![0-9]+]]
-; CHECK-NEXT: br i1 [[CMP13_I]], label [[DOTEXIT_THREAD]], label [[DOTEXIT:%.*]], !dbg [[DBG27:![0-9]+]]
-; CHECK: .exit:
-; CHECK-NEXT: [[PHITMP:%.*]] = icmp sge i32 [[Y]], [[Z]], !dbg [[DBG28:![0-9]+]]
-; CHECK-NEXT: [[COND_FR:%.*]] = freeze i1 [[PHITMP]]
-; CHECK-NEXT: br i1 [[COND_FR]], label [[DOTEXIT_THREAD]], label [[DOTEXIT_THREAD4]], !dbg [[DBG29:![0-9]+]]
-; CHECK: .exit.thread:
-; CHECK-NEXT: br label [[DOTEXIT_THREAD4]], !dbg [[DBG29]]
; CHECK: .exit.thread4:
-; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ [[J]], [[DOTEXIT_THREAD]] ], [ [[ADD3]], [[DOTEXIT]] ], [ [[ADD3]], [[ENTRY:%.*]] ], [ [[ADD3]], [[COND_FALSE_6_I]] ], !dbg [[DBG29]]
+; CHECK-NEXT: [[TMP0:%.*]] = phi i32 {{.*}}, !dbg [[DBG29]]
; CHECK-NEXT: ret i32 [[TMP0]], !dbg [[DBG30:![0-9]+]]
;
; CHECK: [[DBG29]] = !DILocation(line: 13,
>From a0fb47341b9c4a945214535994639c9761559339 Mon Sep 17 00:00:00 2001
From: Apochens <52285902006 at stu.ecnu.edu.cn>
Date: Thu, 9 May 2024 13:48:54 +0000
Subject: [PATCH 4/4] format
---
llvm/lib/Transforms/Scalar/JumpThreading.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/Transforms/Scalar/JumpThreading.cpp b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
index 31ac33217fe53..37ee00d101cbb 100644
--- a/llvm/lib/Transforms/Scalar/JumpThreading.cpp
+++ b/llvm/lib/Transforms/Scalar/JumpThreading.cpp
@@ -1281,7 +1281,7 @@ bool JumpThreadingPass::simplifyPartiallyRedundantLoad(LoadInst *LoadI) {
if (AvailableVal->getType() != LoadI->getType()) {
AvailableVal = CastInst::CreateBitOrPointerCast(
AvailableVal, LoadI->getType(), "", LoadI->getIterator());
- cast<Instruction>(AvailableVal)->setDebugLoc(LoadI->getDebugLoc());
+ cast<Instruction>(AvailableVal)->setDebugLoc(LoadI->getDebugLoc());
}
LoadI->replaceAllUsesWith(AvailableVal);
LoadI->eraseFromParent();
More information about the llvm-commits
mailing list