-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DebugInfo][SimplifyCFG] Fully propagate merged invoke DILocations #114235
Conversation
Currently when we merge invokes as part of SimplifyCFG we apply a merge of the invoke DILocations to the merged invoke. We also insert an unconditional branch to the merged invoke at the positions previously occupied by the original invokes; as this branch is part of the substitution for the invoke it has replaced, we should propagate the original invoke DebugLoc to it.
@llvm/pr-subscribers-llvm-transforms @llvm/pr-subscribers-debuginfo Author: Stephen Tozer (SLTozer) ChangesCurrently when we merge invokes as part of SimplifyCFG we apply a merge of the invoke DILocations to the merged invoke. We also insert an unconditional branch to the merged invoke at the positions previously occupied by the original invokes; as this branch is part of the substitution for the invoke it has replaced, we should propagate the original invoke DebugLoc to it. Full diff: https://github.com/llvm/llvm-project/pull/114235.diff 2 Files Affected:
diff --git a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
index 72228b445a8b6e..9c8a465fd876fd 100644
--- a/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/llvm/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -2917,7 +2917,10 @@ static void mergeCompatibleInvokesImpl(ArrayRef<InvokeInst *> Invokes,
// to the block with the merged `invoke`.
for (BasicBlock *OrigSuccBB : successors(II->getParent()))
OrigSuccBB->removePredecessor(II->getParent());
- BranchInst::Create(MergedInvoke->getParent(), II->getParent());
+ auto *BI = BranchInst::Create(MergedInvoke->getParent(), II->getParent());
+ // The unconditional branch is part of the replacement for the original
+ // invoke, so should use its DebugLoc.
+ BI->setDebugLoc(II->getDebugLoc());
bool Success = MergedInvoke->tryIntersectAttributes(II);
assert(Success && "Merged invokes with incompatible attributes");
// For NDEBUG Compile
diff --git a/llvm/test/Transforms/SimplifyCFG/dbgloc-merge-invoke.ll b/llvm/test/Transforms/SimplifyCFG/dbgloc-merge-invoke.ll
new file mode 100644
index 00000000000000..8f6ffd0dbd0c88
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/dbgloc-merge-invoke.ll
@@ -0,0 +1,74 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -p="simplifycfg<sink-common-insts>" -S | FileCheck %s
+
+;; Tests that when we merge the invokes and use a select to choose the argument
+;; value, the merged invoke and select use the merged DILocation from the
+;; original invokes.
+
+target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare ptr @baz()
+
+define i32 @foo(i1 %call66, ptr %.str.8) personality ptr null {
+; CHECK-LABEL: define i32 @foo(
+; CHECK-SAME: i1 [[CALL66:%.*]], ptr [[DOTSTR_8:%.*]]) personality ptr null {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CALL661:%.*]] = invoke i1 @bar(ptr null)
+; CHECK-NEXT: to label %[[INVOKE_CONT65:.*]] unwind label %[[LPAD45_LOOPEXIT_SPLIT_LP_LOOPEXIT_SPLIT_LP:.*]]
+; CHECK: [[COMMON_RET:.*]]:
+; CHECK-NEXT: ret i32 0
+; CHECK: [[LPAD45_LOOPEXIT_SPLIT_LP_LOOPEXIT_SPLIT_LP]]:
+; CHECK-NEXT: [[LPAD_LOOPEXIT_SPLIT_LP1114:%.*]] = landingpad { ptr, i32 }
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: br label %[[COMMON_RET]]
+; CHECK: [[INVOKE_CONT65]]:
+; CHECK-NEXT: [[DOTSTR_8_:%.*]] = select i1 [[CALL66]], ptr [[DOTSTR_8]], ptr null, !dbg [[DBG3:![0-9]+]]
+; CHECK-NEXT: [[TMP0:%.*]] = invoke ptr @baz(ptr null, ptr [[DOTSTR_8_]])
+; CHECK-NEXT: to label %[[COMMON_RET]] unwind label %[[LPAD45_LOOPEXIT_SPLIT_LP_LOOPEXIT_SPLIT_LP]], !dbg [[DBG3]]
+;
+entry:
+ %call661 = invoke i1 @bar(ptr null)
+ to label %invoke.cont65 unwind label %lpad45.loopexit.split-lp.loopexit.split-lp
+
+common.ret: ; preds = %if.else, %if.then67, %lpad45.loopexit.split-lp.loopexit.split-lp
+ ret i32 0
+
+lpad45.loopexit.split-lp.loopexit.split-lp: ; preds = %if.else, %if.then67, %entry
+ %lpad.loopexit.split-lp1114 = landingpad { ptr, i32 }
+ cleanup
+ br label %common.ret
+
+invoke.cont65: ; preds = %entry
+ br i1 %call66, label %if.then67, label %if.else
+
+if.then67: ; preds = %invoke.cont65
+ %call69 = invoke ptr @baz(ptr null, ptr %.str.8)
+ to label %common.ret unwind label %lpad45.loopexit.split-lp.loopexit.split-lp, !dbg !4
+
+if.else: ; preds = %invoke.cont65
+ %call71 = invoke ptr @baz(ptr null, ptr null)
+ to label %common.ret unwind label %lpad45.loopexit.split-lp.loopexit.split-lp, !dbg !8
+}
+
+declare i1 @bar()
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!3}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang version 20.0.0git")
+!1 = !DIFile(filename: "List.cpp", directory: "/tmp")
+!2 = !{}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = !DILocation(line: 10, column: 20, scope: !6)
+!6 = distinct !DISubprogram(name: "ListArchives", linkageName: "foo", scope: !1, file: !1, line: 416, type: !7, scopeLine: 425, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !2)
+!7 = distinct !DISubroutineType(types: !2)
+!8 = !DILocation(line: 10, column: 10, scope: !6)
+;.
+; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: [[META1:![0-9]+]], producer: "{{.*}}clang version {{.*}}", isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug)
+; CHECK: [[META1]] = !DIFile(filename: "List.cpp", directory: {{.*}})
+; CHECK: [[DBG3]] = !DILocation(line: 10, scope: [[META4:![0-9]+]])
+; CHECK: [[META4]] = distinct !DISubprogram(name: "ListArchives", linkageName: "foo", scope: [[META1]], file: [[META1]], line: 416, type: [[META5:![0-9]+]], scopeLine: 425, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META6:![0-9]+]])
+; CHECK: [[META5]] = distinct !DISubroutineType(types: [[META6]])
+; CHECK: [[META6]] = !{}
+;.
|
Currently when we merge invokes as part of SimplifyCFG we apply a merge of the invoke DILocations to the merged invoke. We also insert an unconditional branch to the merged invoke at the positions previously occupied by the original invokes; as this branch is part of the substitution for the invoke it has replaced, we should propagate the original invoke DebugLoc to it.
Found using #107279.